Golang中使用GORM和SQLite实现多重检查约束的方法

Golang中使用GORM和SQLite实现多重检查约束的方法 基本上我有这样一个表:

type Table struct {
  Username `gorm:"column:username;type:text;check:username>=3;check:username<=20;unique;not null"`
}

我的目标是让用户名满足这个条件: username >= 3 && username <= 20

但当我运行这段代码时:

data := Table{Username: "aValidUsername"}
err := db.Debug().Model(&data).Save(data).Error

我遇到了这个错误: constraint failed: CHECK constraint failed: chk_table_username (275)

这让我觉得我的标签写错了。正确的做法是什么?


更多关于Golang中使用GORM和SQLite实现多重检查约束的方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

5 回复

我已经找到了答案:

type Table struct {
  Username string `gorm:"column:username;type:text;check:length(username)>=3;check:length(username)<=20;unique;not null"`
}

更多关于Golang中使用GORM和SQLite实现多重检查约束的方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


另一个回答可能是“根本不要使用GORM” 😂 😂

更新: 我的回答是错误的,因为这两个检查条件的作用就像是使用 OR 运算符连接起来的。

这是正确的方法:

type Table struct {
  Username string `gorm:"column:username;type:text;check:(length(username)>=3 and length(username)<=20);unique;not null"`
}

if username >=3 && username <=20 == check:(length(username)>=3 and length(username)<=20)

Willy:

我基本上有这样一个表:

type Table struct {
  Username `gorm:"column:username;type:text;check:username>=3;check:username<=20;unique;not null"`
}

我的目标是让用户名满足这个条件: username >= 3 && username <= 20

但是当我运行这段代码时:

data := Table{Username: "aValidUsername"}
err := db.Debug().Model(&data).Save(data).Error

我得到了这个错误: constraint failed: CHECK constraint failed: chk_table_username (275)

这让我觉得我的标签写错了。正确的做法是什么?

使用这个标签,GORM 将生成一个 SQLite 检查约束,对 Username 列强制执行指定的条件。当你将数据保存到数据库时,数据会接受这些约束的检查,任何不满足这些条件的数据都将导致约束违反错误。

在Golang中使用GORM和SQLite实现多重检查约束的正确方法如下:

type Table struct {
    Username string `gorm:"column:username;type:text;check:length(username) >= 3 AND length(username) <= 20;unique;not null"`
}

或者使用单独的约束名称:

type Table struct {
    Username string `gorm:"column:username;type:text;check:chk_username_length CHECK (length(username) >= 3 AND length(username) <= 20);unique;not null"`
}

对于更复杂的多重约束,可以使用多个check标签:

type Table struct {
    Username string `gorm:"column:username;type:text;check:length(username) >= 3;check:length(username) <= 20;unique;not null"`
}

完整示例代码:

package main

import (
    "fmt"
    "gorm.io/driver/sqlite"
    "gorm.io/gorm"
)

type Table struct {
    ID       uint   `gorm:"primaryKey"`
    Username string `gorm:"column:username;type:text;check:length(username) >= 3 AND length(username) <= 20;unique;not null"`
}

func main() {
    db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
    if err != nil {
        panic("failed to connect database")
    }

    db.AutoMigrate(&Table{})

    // 有效数据
    validData := Table{Username: "validUser"}
    result := db.Create(&validData)
    if result.Error != nil {
        fmt.Printf("Error: %v\n", result.Error)
    } else {
        fmt.Println("Valid data inserted successfully")
    }

    // 无效数据 - 太短
    invalidShort := Table{Username: "ab"}
    result = db.Create(&invalidShort)
    if result.Error != nil {
        fmt.Printf("Expected error for short username: %v\n", result.Error)
    }

    // 无效数据 - 太长
    invalidLong := Table{Username: "thisusernameistoolongforvalidation"}
    result = db.Create(&invalidLong)
    if result.Error != nil {
        fmt.Printf("Expected error for long username: %v\n", result.Error)
    }
}

如果需要更复杂的约束逻辑,可以使用GORM的迁移功能手动添加约束:

db.Exec(`
    ALTER TABLE tables 
    ADD CONSTRAINT chk_username_length 
    CHECK (length(username) >= 3 AND length(username) <= 20)
`)

或者使用GORM的Check约束方法:

db.Migrator().CreateConstraint(&Table{}, "chk_username_length")

这样就能正确实现SQLite中的多重检查约束了。

回到顶部