版本管理

drizzle-seed 使用版本管理来处理静态和动态数据的输出。为确保真正的 确定性,请确保在使用相同 seed 数字时,值保持不变。如果静态数据源或动态数据生成逻辑发生更改,版本将会更新,从而允许 你在继续使用先前版本和使用最新版本之间进行选择。

你可以升级到最新的 drizzle-seed 版本以获取新功能,例如新增 生成器,同时在需要时仍可使用先前版本来保持确定性的输出。这 在你需要依赖现有确定性数据,同时又想使用新功能时尤其有用。

await seed(db, schema, { version: '2' });

历史

api versionnpm versionChanged generators
v10.1.1
v20.2.1string(), interval({ isUnique: true })
v30.4.0hash generating function
v4 (LTS) 1.0.0-beta.8uuid

底层是如何工作的?

这并不是真正的 API 变更;这只是一个示例,展示我们将如何推进 drizzle-seed 的版本管理。

例如,lastName 生成器发生了变化,并且该生成器的新版本 V2 可用。

后来,firstName 生成器也发生了变化,使得该生成器的 V3 版本可用。

V1V2V3(最新)
LastNameGenLastNameGenV1LastNameGenV2
FirstNameGenFirstNameGenV1FirstNameGenV3
使用 3 版的 firstName 生成器和 2 版的 lastName 生成器
await seed(db, schema);

如果你还不准备立即使用最新版本的生成器,你可以指定要使用的最大版本

使用 1 版的 firstName 生成器和 2 版的 lastName 生成器
await seed(db, schema, { version: '2' });
使用 1 版的 firstName 生成器和 1 版的 lastName 生成器。
await seed(db, schema, { version: '1' });

版本 2

唯一 interval 生成器已更改

升级原因

旧版本的生成器可能会生成诸如 1 minute 60 seconds2 minutes 0 seconds 这样的区间,并将它们视为不同的区间。 然而,当 1 minute 60 seconds 这个区间插入到 MySQL 数据库时,它会被自动转换为 2 minutes 0 seconds。因此,之后再尝试将 2 minutes 0 seconds 区间插入到唯一列时,会导致错误

如果你在播种脚本中使用了唯一的 interval 生成器,则会受到影响,如下方脚本所示:

import { binary, char, mysqlTable, text, varbinary, varchar } from 'drizzle-orm/mysql-core';
import { drizzle } from 'drizzle-orm/mysql2';
import { seed } from "drizzle-seed";

const intervals = mysqlTable('intervals', {
	interval1: char({ length: 255 }).unique(),
	interval2: char({ length: 255 }),
	interval3: varchar({ length: 255 }).unique(),
	interval4: varchar({ length: 255 }),
	interval5: binary({ length: 255 }).unique(),
	interval6: binary({ length: 255 }),
	interval7: varbinary({ length: 255 }).unique(),
	interval8: varbinary({ length: 255 }),
	interval9: text(),
});

async function main() {
	const db = drizzle(process.env.DATABASE_URL!);

	await seed(db, { intervals }, { version: '2' }).refine((f) => ({
		intervals: {
			columns: {
				interval: f.interval({ isUnique: true }),
				interval1: f.interval({ isUnique: true }),
				interval2: f.interval({ isUnique: true }),
				interval3: f.interval({ isUnique: true }),
				interval4: f.interval({ isUnique: true }),
				interval5: f.interval({ isUnique: true }),
				interval6: f.interval({ isUnique: true }),
				interval7: f.interval({ isUnique: true }),
				interval8: f.interval({ isUnique: true }),
				interval9: f.interval({ isUnique: true }),
			},
		},
	}));
}

main();

string 生成器已更改:非唯一和唯一均有变化

升级原因

能够基于文本列的长度生成唯一字符串(例如,varchar(20)

如果你的表包含一个带最大长度参数的类文本类型列,或者一个类文本类型的唯一列,则会受到影响:

import { binary, char, mysqlTable, varbinary, varchar } from 'drizzle-orm/mysql-core';
import { drizzle } from 'drizzle-orm/mysql2';
import { seed } from "drizzle-seed";

const strings = mysqlTable('strings', {
	string1: char({ length: 255 }).unique(),
	string2: char({ length: 255 }),
	string3: varchar({ length: 255 }).unique(),
	string4: varchar({ length: 255 }),
	string5: binary({ length: 255 }).unique(),
	string6: binary({ length: 255 }),
	string7: varbinary({ length: 255 }).unique(),
	string8: varbinary({ length: 255 }),
});

async function main() {
	const db = drizzle(process.env.DATABASE_URL!);

	await seed(db, { strings });
}

main();

如果你在播种脚本中使用了 string 生成器,则会受到影响,如下方脚本所示:

import { binary, char, mysqlTable, text, varbinary, varchar } from 'drizzle-orm/mysql-core';
import { drizzle } from 'drizzle-orm/mysql2';
import { seed } from "drizzle-seed";

const strings = mysqlTable('strings', {
	string1: char({ length: 255 }).unique(),
	string2: char({ length: 255 }),
	string3: char({ length: 255 }),
	string4: varchar({ length: 255 }).unique(),
	string5: varchar({ length: 255 }),
	string6: varchar({ length: 255 }),
	string7: binary({ length: 255 }).unique(),
	string8: binary({ length: 255 }),
	string9: binary({ length: 255 }),
	string10: varbinary({ length: 255 }).unique(),
	string11: varbinary({ length: 255 }),
	string12: varbinary({ length: 255 }),
	string13: text(),
});

async function main() {
	const db = drizzle(process.env.DATABASE_URL!);

	await seed(db, { strings }).refine((f) => ({
		strings: {
			columns: {
				string1: f.string({ isUnique: true }),
				string2: f.string({ isUnique: true }),
				string3: f.string(),
				string4: f.string({ isUnique: true }),
				string5: f.string({ isUnique: true }),
				string6: f.string(),
				string7: f.string({ isUnique: true }),
				string8: f.string({ isUnique: true }),
				string9: f.string(),
				string10: f.string({ isUnique: true }),
				string11: f.string({ isUnique: true }),
				string12: f.string(),
				string13: f.string({ isUnique: true }),
			},
		},
	}));
}

main();

版本 3

hash 生成函数已更改

升级原因

之前版本的 hash 生成函数会根据使用的是 Bun 还是 Node.js 生成不同的哈希,并且哈希在不同版本的 Node.js 之间也会有所不同。

新的 hash 生成函数无论 Node.js 或 Bun 的版本如何,都会生成相同的哈希,从而在所有版本中实现确定性的数据生成。

与之前版本相比,所有生成器的输出值都会不同,即使使用相同的 seed number 也是如此。

用法

await seed(db, schema);
// 或显式指定
await seed(db, schema, { version: '3' });

切换到旧版本

之前版本的 hash 生成函数是 v1。

await seed(db, schema, { version: '1' });

要在保持 v1 hash 生成函数的同时使用 v2 生成器:

await seed(db, schema, { version: '2' });

版本 4

uuid 生成器已更改

升级原因

旧版本的 uuid 生成器生成的 UUID 值无法通过 Zod 的 v4 UUID 验证。

example

import { createSelectSchema } from 'drizzle-zod';
import { seed } from 'drizzle-seed';

await seed(db, { uuidTest: schema.uuidTest }, { count: 1 }).refine((funcs) => ({
		uuidTest: {
			columns: {
				col1: funcs.uuid()
			}
		}
	})
);

const uuidSelectSchema = createSelectSchema(schema.uuidTest);
const res = await db.select().from(schema.uuidTest);
// 下面这一行在使用旧版本的 uuid 生成器时会抛出错误
uuidSelectSchema.parse(res[0]);

用法

await seed(db, schema);
// 或显式指定
await seed(db, schema, { version: '4' });

切换到旧版本

之前版本的 uuid 生成器是 v1。

await seed(db, schema, { version: '1' });

要在保留 v1 uuid 生成器的同时使用 v2 生成器:

await seed(db, schema, { version: '2' });

要在保留 v1 uuid 生成器的同时使用 v3 生成器:

await seed(db, schema, { version: '3' });