Models
Models are defined using Model
in the configuration.
Model("book",
Field("id", "string", PrimaryKey),
Field("created_at", "time"),
Field("name", "string"),
)
Fields
Fields are defined using Field
, specifying the name, the type, and a list of potential options.
Field("id", "string", options...),
Nullable fields
Fields can be defined nullable using Null
.
Model("user",
Field("id", "string", PrimaryKey),
Field("created_at", "time"),
Field("deleted_at", "time", Null),
)
Default values
Setting field default values is intentionally NOT supported in sqlbunny.
Columns get SQL defaults set to the Go zero value if not nullable, and no default if nullable (ie the default is null
). This means 0
for numeric types, ""
for strings, etc. This matches the Go behavior when initializing struct fields.
Consider what would happen in this case if default values were hypothetically supported:
Model("user",
Field("id", "string", PrimaryKey),
Field("is_active", "bool", Default(true)),
)
u := &models.User{ID: "1234"}
u.Insert(ctx)
Insert
would receive is_active = false
, but it can't know if it's false
because it was never set (so the default of true
should be used) or it has been explicitly set to false
(so the inserted row should have false
).
Both choices can be surprising to users and lead to potential bugs. To avoid this, sqlbunny takes an opinionated stance, and makes SQL's behavior more closely match Go's.
Primary key
Models must have exactly one primary key.
If the primary key contains one column, you can specify it in the Field
declaration.
Field("id", "string", PrimaryKey),
If the primary key contains multiple columns, you have to specify it with its own declaration.
Field("user_name", "string"),
Field("repo_name", "string"),
PrimaryKey("user_name", "repo_name"),
Indexes
Similarly to primary keys, indexes can be defined in the field declaration or with their own declaration.
Field("created_at", "time", Index),
Field("created_at", "time"),
Field("user_id", "string"),
Index("user_id", "created_at"),
Unique constraints
Same as indexes.
Field("user_name", "string", Unique),
Field("user_name", "time"),
Field("repo_name", "string"),
Unique("user_name", "repo_name"),
Foreign keys
You can declare a field to be a foreign key to another model. In this case, the field type must be equal to the destination model primary key type.
Field("user_id", "string", ForeignKey("user")),
Foreign keys to models with a multi-column primary key are also supported.
Model("repo",
Field("organization_id", "string"),
Field("repo_id", "string"),
Field("path", "string"),
PrimaryKey("organization_id", "repo_id"),
...
),
Model("repo_file",
Field("organization_id", "string"),
Field("repo_id", "string"),
ModelForeignKey("repo", "organization_id", "repo_id"),
Field("path", "string"),
PrimaryKey("organization_id", "repo_id", "path"),
),
Foreign keys spanning multiple columns (needed to refer to models with multi-column primary keys) are currently not supported.
Field tags
Struct field tags can be specified with Tag
.
Field("user_name", "string", Tag("json", "userName"), Tag("foo", "bar")),
would generate the following struct field:
UserName string `bunny:"user_name" json:"userName" foo:"bar"`