go-gorm / clickhouse

GORM clickhouse driver
MIT License
244 stars 72 forks source link

SkipDefaultTransaction = true时,没有办法通过gorm提供的方法写入数据 #139

Open steden opened 10 months ago

steden commented 10 months ago

当我复用gorm.Open的*gorm.DB,且使用CreateInBatches方法写批量写入数据,总是返回:

在clickhouse表中,也没有写入成功。

最后没办法,通过调用CreateInBatches方法,并且开启Dry(为了拿到SQL)

session := gorm.Open(...)
    session.ormClient = session.ormClient.Session(&gorm.Session{
        SkipDefaultTransaction: session.ormClient.SkipDefaultTransaction,
        Logger:                 session.ormClient.Logger,
        DryRun:                 true,
    })
session.ormClient.Callback().Create().After("trace_before").Register("get_sql", func(db *gorm.DB) {
    session.SQL = db.Dialector.Explain(db.Statement.SQL.String(), db.Statement.Vars...)
    db.Callback().Create().Remove("get_sql")
})
session.CreateInBatches(arr,2000)

利用Create回调,拿到SQL后。再手动执行SQL:

session := gorm.Open(...)
session.Exec(SQL)

只有每次都gorm.Open,然后把生成的SQL,用Exec执行,才能成功。

steden commented 10 months ago

即使我使用github.com/ClickHouse/clickhouse-go/v2 v2.8.3 也没办法成功。

这个问题困扰了我2天,最后只能用我上面的方式来临时解决。麻烦作者看是否能重现并修复,谢谢。

steden commented 10 months ago

问题终于找到了。

        gormDB, err := gorm.Open(dbConfig.getDriver(), &gorm.Config{
            SkipDefaultTransaction:                   true,
            DisableForeignKeyConstraintWhenMigrating: true, // 禁止自动创建数据库外键约束
            Logger: logger.New(
                log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
                logger.Config{
                    SlowThreshold:             time.Second, // 慢 SQL 阈值
                    Colorful:                  false,       // 禁用彩色打印
                    IgnoreRecordNotFoundError: true,
                    ParameterizedQueries:      false,
                    LogLevel:                  logger.Error, // Log level
                },
            ),
        })

SkipDefaultTransaction = true时,没有办法通过gorm提供的方法写入。

a2798528624 commented 4 months ago

这个和gorm没啥太大关系,这个主要是因为gorm默认使用的是github.com/ClickHouse/clickhouse-go/v2这个引擎。 这个引擎会有buffer,这个在commit的时候才刷新这个buffer。