数据库端 类型:仅限 STORED
工作原理
功能
通过预先计算复杂表达式来简化数据访问。
通过对生成的列添加索引支持来增强查询性能。
限制
无法指定默认值。
表达式不能引用其他生成的列或包含子查询。
需要更改模式才能修改生成的列表达式。
无法直接在主键、外键或唯一约束中使用
更多信息,请查看 PostgreSQL 文档
Drizzle 端 在 Drizzle 中,你可以在任何列类型上指定 .generatedAlwaysAs()
函数,并添加支持的 SQL 查询,该查询将为你生成此列数据。
功能 此函数可以通过三种方式接受生成的表达式:
string
export const test = pgTable ( "test" , {
generatedName : text ( "gen_name" ) .generatedAlwaysAs ( `hello world!` ) ,
});
CREATE TABLE IF NOT EXISTS "test" (
"gen_name" text GENERATED ALWAYS AS (hello world!) STORED
);
sql
标签 - 如果你希望 Drizzle 为你转义某些值
export const test = pgTable ( "test" , {
generatedName : text ( "gen_name" ) .generatedAlwaysAs ( sql `hello "world"!` ) ,
});
CREATE TABLE IF NOT EXISTS "test" (
"gen_name" text GENERATED ALWAYS AS (hello "world" !) STORED
);
callback
- 如果你需要引用表中的列
export const test = pgTable ( "test" , {
name : text ( "first_name" ) ,
generatedName : text ( "gen_name" ) .generatedAlwaysAs (
() : SQL => sql `hi, ${ test .name } !`
) ,
});
CREATE TABLE IF NOT EXISTS "test" (
"first_name" text ,
"gen_name" text GENERATED ALWAYS AS (hi, "test" . "first_name" !) STORED
);
带有全文搜索的生成列示例
import { SQL , sql } from "drizzle-orm" ;
import { customType , index , integer , pgTable , text } from "drizzle-orm/pg-core" ;
const tsVector = customType <{ data : string }>({
dataType () {
return "tsvector" ;
} ,
});
export const test = pgTable (
"test" ,
{
id : integer ( "id" ) .primaryKey () .generatedAlwaysAsIdentity () ,
content : text ( "content" ) ,
contentSearch : tsVector ( "content_search" , {
dimensions : 3 ,
}) .generatedAlwaysAs (
() : SQL => sql `to_tsvector('english', ${ test .content } )`
) ,
} ,
(t) => [
index ( "idx_content_search" ) .using ( "gin" , t .contentSearch)
]
);
CREATE TABLE IF NOT EXISTS "test" (
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY ( sequence name "test_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1 ),
"content" text ,
"content_search" "tsvector" GENERATED ALWAYS AS (to_tsvector( 'english' , "test" . "content" )) STORED
);
--> statement-breakpoint
CREATE INDEX IF NOT EXISTS "idx_content_search" ON "test" USING gin ( "content_search" );
数据库端 类型:STORED
, VIRTUAL
工作原理
在表架构中使用表达式进行定义。
虚拟列在读取操作期间计算。
存储列在写入操作期间计算并存储。
功能
限制
更多信息,请查看 MySQL 修改生成的列 文档和 MySQL 创建生成的列 文档
Drizzle 端 功能 string
export const test = mysqlTable ( "test" , {
generatedName : text ( "gen_name" ) .generatedAlwaysAs ( `hello world!` ) ,
});
CREATE TABLE ` test ` (
`gen_name` text GENERATED ALWAYS AS (hello world!) VIRTUAL
);
sql
标签 - 如果你希望 Drizzle 为你转义某些值
export const test = mysqlTable ( "test" , {
generatedName : text ( "gen_name" ) .generatedAlwaysAs ( sql `hello "world"!` ) ,
});
CREATE TABLE ` test ` (
`gen_name` text GENERATED ALWAYS AS (hello "world" !) VIRTUAL
);
callback
- 如果你需要引用表中的列
export const test = mysqlTable ( "test" , {
name : text ( "first_name" ) ,
generatedName : text ( "gen_name" ) .generatedAlwaysAs (
() : SQL => sql `hi, ${ test .name } !`
) ,
});
CREATE TABLE ` test ` (
`first_name` text ,
`gen_name` text GENERATED ALWAYS AS (hi, `test` . `first_name` !) VIRTUAL
);
限制 Drizzle Kit 对 push
命令也存在限制:
你无法使用 push
更改生成的约束表达式和类型。Drizzle-kit 将忽略此更改。要使其正常工作,你需要先执行 drop the column
、push
,然后执行 add a column with a new expression
。这样做是因为数据库端的映射很复杂,模式表达式会在数据库端被修改,并且在自省时,我们会得到不同的字符串。我们无法确定你是否更改了此表达式,或者它是否已被数据库更改和格式化。只要这些是生成的列,并且 push
主要用于在本地数据库上进行原型设计,那么 drop
和 create
生成的列应该会很快。由于这些列是 generated
,因此所有数据都将被恢复。
generate
应该没有任何限制
export const users = mysqlTable ( "users" , {
id : int ( "id" ) ,
id2 : int ( "id2" ) ,
name : text ( "name" ) ,
storedGenerated : text ( "stored_gen" ) .generatedAlwaysAs (
() : SQL => sql ` ${ users .name } || 'hello'` ,
{ mode : "stored" }
) ,
virtualGenerated : text ( "virtual_gen" ) .generatedAlwaysAs (
() : SQL => sql ` ${ users .name } || 'hello'` ,
{ mode : "virtual" }
) ,
})
CREATE TABLE ` users ` (
`id` int ,
`id2` int ,
`name` text ,
`stored_gen` text GENERATED ALWAYS AS ( `users` . `name` || 'hello' ) STORED,
`virtual_gen` text GENERATED ALWAYS AS ( `users` . `name` || 'hello' ) VIRTUAL
);
数据库端 类型:STORED
, VIRTUAL
工作原理
在表架构中使用表达式进行定义。
虚拟列在读取操作期间计算。
存储列在写入操作期间计算并存储。
功能
限制
更多信息,请查看 SQLite 文档
Drizzle 端 功能 string
export const test = sqliteTable ( "test" , {
generatedName : text ( "gen_name" ) .generatedAlwaysAs ( `hello world!` ) ,
});
CREATE TABLE ` test ` (
`gen_name` text GENERATED ALWAYS AS (hello world!) VIRTUAL
);
sql
标签 - 如果你希望 Drizzle 为你转义某些值
export const test = sqliteTable ( "test" , {
generatedName : text ( "gen_name" ) .generatedAlwaysAs ( sql `hello "world"!` ) ,
});
CREATE TABLE ` test ` (
`gen_name` text GENERATED ALWAYS AS (hello "world" !) VIRTUAL
);
callback
- 如果你需要引用表中的列
export const test = sqliteTable ( "test" , {
name : text ( "first_name" ) ,
generatedName : text ( "gen_name" ) .generatedAlwaysAs (
() : SQL => sql `hi, ${ test .name } !`
) ,
});
CREATE TABLE ` test ` (
`first_name` text ,
`gen_name` text GENERATED ALWAYS AS (hi, "first_name" !) VIRTUAL
);
限制 Drizzle Kit 对 push
和 generate
命令也存在限制:
你无法使用现有表中的存储类型更改生成的约束表达式。你需要删除此表并重新创建。这是由于 SQLite 对此类操作的限制。我们将在未来的版本中处理这种情况(这将涉及创建带有数据迁移功能的新表)。
出于与上述相同的原因,你无法将 stored
生成的表达式添加到现有列。但是,你可以将 virtual
表达式添加到现有列。
出于与上述相同的原因,你无法更改现有列中 stored
生成的表达式。但是,你可以更改 virtual
表达式。
出于与上述相同的原因,你无法将生成的约束类型从 virtual
更改为 stored
。但是,你可以将 stored
更改为 virtual
。
export const users = sqliteTable ( "users" , {
id : int ( "id" ) ,
name : text ( "name" ) ,
storedGenerated : text ( "stored_gen" ) .generatedAlwaysAs (
() : SQL => sql ` ${ users .name } || 'hello'` ,
{ mode : "stored" }
) ,
virtualGenerated : text ( "virtual_gen" ) .generatedAlwaysAs (
() : SQL => sql ` ${ users .name } || 'hello'` ,
{ mode : "virtual" }
) ,
});
CREATE TABLE ` users ` (
`id` integer ,
`name` text ,
`stored_gen` text GENERATED ALWAYS AS ( "name" || 'hello' ) STORED,
`virtual_gen` text GENERATED ALWAYS AS ( "name" || 'hello' ) VIRTUAL
);