亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何從 GORM 結構模型生成 SQL 代碼?

如何從 GORM 結構模型生成 SQL 代碼?

Go
慕勒3428872 2022-08-09 20:16:09
我正在使用 goose 來管理我的數據庫遷移,但我需要直接在遷移文件中寫入 SQL 句子。有一種方法可以直接從GORM模型生成SQL?
查看完整描述

3 回答

?
達令說

TA貢獻1821條經驗 獲得超6個贊

遺憾的是,使用該選項不會使遷移 SQL 語句對調用方可用,就像使用普通查詢一樣。gorm.Session{DryRun: true}


我現在能看到的唯一方法是在通過重新實現接口來記錄遷移時捕獲遷移運行的SQL。具體來說就是方法。gorm.io/gorm/logger.InterfaceTrace


type Interface interface {

    LogMode(LogLevel) Interface

    Info(context.Context, string, ...interface{})

    Warn(context.Context, string, ...interface{})

    Error(context.Context, string, ...interface{})

    Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error)

}

在內部,您可以調用該函數參數來獲取 SQL 和 ,您可以執行任何操作。TracefcRowsAffected


例如:


import (

    "time"

    "context"

    "gorm.io/gorm/logger"

)


type RecorderLogger struct {

    logger.Interface

    Statements []string

}


func (r *RecorderLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {

    sql, _ := fc()

    r.Statements = append(r.Statements, sql)

}

現在將其用作:


recorder := RecorderLogger{logger.Default.LogMode(logger.Info)}

session := db.Session(&gorm.Session{

    Logger: &recorder

})

session.AutoMigrate(&Model{}, ...)

// or 

session.Migrator().CreateTable(&Model{}, ...) // or any method therein

// now recorder.Statements contains the statements run during migration

這是非常棘手的,你可能會遇到問題,因為修改數據庫的當前狀態并將其遷移到模型所需的狀態(最多一點),為此,當前數據庫必須反映生產數據庫(或您希望遷移的任何數據庫)的當前狀態。因此,如果您小心,您可以構建該工具來幫助您啟動遷移腳本,但是要正確獲得遷移系統的優勢,例如您需要親自動手使用SQL:)AutoMigrategoose


查看完整回答
反對 回復 2022-08-09
?
紅顏莎娜

TA貢獻1842條經驗 獲得超13個贊

我個人會使用Gorm內部可用的遷移功能,但對于您的情況,我們可以執行以下操作。


首先,Gorm中有一個名為“Dry Run”的功能,您可以使用它來查看在執行查詢時執行的SQL語句。不幸的是,我看不出在使用遷移時這是可能的。所以我建議使用github.com/DATA-DOG/go-sqlmock


我通常會將其用于測試目的,但您可以暫時使用它來獲取單獨遷移所需的SQL。


package main


import (

    "database/sql"

    "time"


    "github.com/DATA-DOG/go-sqlmock"

    "gorm.io/driver/mysql"

    "gorm.io/gorm"

)


type Model struct {

    ID          uint64 `gorm:"primaryKey"`

    Name        string `gorm:"index"`

    Description string

    CreatedAt   time.Time

    LastLogin   sql.NullTime

}


func main() {

    sqlDB, _, err := sqlmock.New()

    if err != nil {

        panic(err)

    }


    gormDB, err := gorm.Open(mysql.New(mysql.Config{

        Conn:                      sqlDB,

        SkipInitializeWithVersion: true,

    }), &gorm.Config{})

    if err != nil {

        panic(err)

    }


    defer sqlDB.Close()


    gormDB.AutoMigrate(&Model{})

}


這將給你一個這樣的結果


all expectations were already fulfilled, call to ExecQuery 'CREATE TABLE `models` (`id` bigint unsigned AUTO_INCREMENT,`name` varchar(191),`description` longtext,`created_at` datetime(3) NULL,`last_login` datetime(3) NULL,PRIMARY KEY (`id`),INDEX idx_models_name (`name`))' with args [] was not expected

[0.003ms] [rows:0] CREATE TABLE `models` (`id` bigint unsigned AUTO_INCREMENT,`name` varchar(191),`description` longtext,`created_at` datetime(3) NULL,`last_login` datetime(3) NULL,PRIMARY KEY (`id`),INDEX idx_models_name (`name`))

其中包含所需的 SQL 語句。這感覺非常笨拙,但會給你你需要的結果


查看完整回答
反對 回復 2022-08-09
?
當年話下

TA貢獻1890條經驗 獲得超9個贊

你可以使用這個庫:https://github.com/sunary/sqlize

它允許您從模型創建sql,還支持模型和現有sql之間的差異遷移。


查看完整回答
反對 回復 2022-08-09
  • 3 回答
  • 0 關注
  • 752 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號