【发布时间】:2021-07-27 01:25:49
【问题描述】:
是否支持使用在 postgreSQL 方言中自动生成的 UUID 类型 id? 对生成的 CREATE TABLE sql 感到非常惊讶,这对于 postgreSQL 方言似乎不正确。
在 PostgreSQL 上通过 queryGenerator.createTableQuery 对 queryInterface.createTable 进行续集,其 PK id 类型为 UUID 和 defaultValue:Sequelize.DataTypes.UUIDV4 似乎没有创建正确的 CREATE TABLE,当未提供 id 值时,它将为 id 创建默认 UUID 值。
在 queryInterface.createTable 的调用下
await queryInterface.createTable(
// 'tableName'
'User2s',
// 'attributes'
{
id: {
allowNull: false,
// autoIncrement: true, // with this "npx sequelize-cli db:migrate" fails with 'ERROR syntax error at or near "SERIAL"' for type UUID. So not using this. This would work if id type was INTEGER (without setting 'defaultValue')
defaultValue: Sequelize.UUIDV4,
// defaultValue: Sequelize.DataTypes.UUIDV4, // tried this instead of above too
// defaultValue: require('sequelize').UUIDV4, // tried this instead of above too
primaryKey: true,
type: Sequelize.UUID
},
firstName: {
type: Sequelize.STRING
},
lastName: {
type: Sequelize.STRING
},
email: {
type: Sequelize.STRING
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
},
// 'options'
{schema: process.env.DB_POSTGRESQL_SCHEMA_NAME}
);
在 SQL 下创建(方言设置为 postgreSQL);
CREATE TABLE exp15c."User2s"
(
id uuid NOT NULL,
"firstName" character varying(255) COLLATE pg_catalog."default",
"lastName" character varying(255) COLLATE pg_catalog."default",
email character varying(255) COLLATE pg_catalog."default",
"createdAt" timestamp with time zone NOT NULL,
"updatedAt" timestamp with time zone NOT NULL,
CONSTRAINT "User2s_pkey" PRIMARY KEY (id)
)
但上面为 postgreSQL 生成的 CREATE TABLE 可能应该是;
CREATE TABLE exp15c."User2s"
(
id uuid DEFAULT uuid_generate_v4(),
"firstName" character varying(255) COLLATE pg_catalog."default",
"lastName" character varying(255) COLLATE pg_catalog."default",
email character varying(255) COLLATE pg_catalog."default",
"createdAt" timestamp with time zone NOT NULL,
"updatedAt" timestamp with time zone NOT NULL,
CONSTRAINT "User2s_pkey" PRIMARY KEY (id)
)
当我看文件时; https://github.com/sequelize/sequelize/blob/9f950cbcbdd659d559496b77c40e0f827b108561/docs/manual/core-concepts/model-basics.md UUID 对于 UUID,请使用 DataTypes.UUID。它成为 PostgreSQL 和 SQLite 的 UUID 数据类型,以及 MySQL 的 CHAR(36) 数据类型。 Sequelize 可以自动为这些字段生成 UUID,只需使用 Sequelize.UUIDV1 或 Sequelize.UUIDV4 作为默认值:
{
type: DataTypes.UUID,
defaultValue: Sequelize.UUIDV4 // Or Sequelize.UUIDV1
}
它基本上说,我上面的用法是正确的。
当我查看 sequelize 源代码时,我看到的是; https://github.com/sequelize/sequelize/blob/9f950cbcbdd659d559496b77c40e0f827b108561/lib/utils.js
const uuidv4 = require('uuid').v4;
function toDefaultValue(value, dialect) {
if (typeof value === 'function') {
const tmp = value();
if (tmp instanceof DataTypes.ABSTRACT) {
return tmp.toSql();
}
return tmp;
}
if (value instanceof DataTypes.UUIDV1) {
return uuidv1();
}
if (value instanceof DataTypes.UUIDV4) {
return uuidv4();
}
if (value instanceof DataTypes.NOW) {
return now(dialect);
}
if (Array.isArray(value)) {
return value.slice();
}
if (_.isPlainObject(value)) {
return { ...value };
}
return value;
}
exports.toDefaultValue = toDefaultValue;
及以上方法用于 https://github.com/sequelize/sequelize/blob/9f950cbcbdd659d559496b77c40e0f827b108561/lib/model.js _initValues(值,选项){ 但不确定它是否真的适用于我的用例。
上面生成的 CREATE TABLE sql 执行并创建表,但是当我们尝试在没有 id 值的情况下插入时不起作用,这是我正在尝试做的。
要非常详细; 我正在通过如下 sequelize-cli 命令使用 sequelize; 0) 确保您的 postgreSQL 数据库具有新模式 'exp15c' 初始化 sequelize 目录和文件 npx sequelize-cli 初始化
-
创建模型和迁移 npx sequelize-cli model:generate --name User2 --attributes firstName:string,lastName:string,email:string 将模型创建为;
'使用严格'; 常量 { 模型 } = 要求('续集'); module.exports = (sequelize, DataTypes) => { 类 User2 扩展模型 { 静态关联(模型){ // 这里定义关联 } }; 用户2.init({ 名字:DataTypes.STRING, 姓氏:DataTypes.STRING, 电子邮件:DataTypes.STRING }, { 续集, 模型名称:'用户2', }); 返回用户2; }
-
手动更新生成的迁移文件以在“up”中包含上述代码
'使用严格'; 模块.exports = { 向上:异步(queryInterface,Sequelize)=> { // 上面提供的带有“await queryInterface._createTable(”的代码片段在这里 }, 下来:异步(queryInterface,Sequelize)=> { 等待 queryInterface.dropTable('User2s'); } };
-
执行上述迁移 npx sequelize-cli 数据库:迁移 观察它使用上面的 CREATE TABLE sql 创建了 User2s 表
-
为 User2 创建“种子”文件 npx sequelize-cli 种子:生成 --name init-user2
-
手动将上面创建的 User2 种子更新为(注意没有指定 id 值,因为它是通过默认机制自动分配的);
'使用严格'; 模块.exports = { 向上:异步(queryInterface,Sequelize)=> { 等待 queryInterface.bulkInsert( {tableName:'User2s',架构:'exp15c'}, [ {名:'ilker',姓:'kiris',电子邮件:'ilker@gmail.com',createdAt:新日期(),更新日期:新日期()}, { firstName:'selcuk',lastName:'gecer',电子邮件:'selcuk@gmail.com',createdAt:新日期(),updatedAt:新日期()}, {名字:'turhan',姓氏:'bozkurt',电子邮件:'turhan@gmail.com',createdAt:新日期(),updatedAt:新日期()} ],{} ); },
down: async (queryInterface, Sequelize) => { 等待 queryInterface.bulkDelete('User2s', null, {}); } };
-
为 User2 执行上述种子 npx sequelize-cli db:seed:all 注意以上失败 错误:关系“User2s”的“id”列中的空值违反非空约束 因为生成的 CREATE TABLE sql 并没有真正使用 defaultValue 变量
【问题讨论】:
标签: sequelize.js