如果主键为 null,则 Sequelize js upsert 控件
Sequelize js upsert controls if primary key is null
我正在尝试将 sequelize js 的 upsert 方法与 postgresql 一起使用。我正在通过 sequelize-auto js
生成模型
我的 table 就像:
CREATE SEQUENCE TBL_CITY_LANG_SEQ;
CREATE TABLE TBL_CITY_LANG(
ID BIGINT DEFAULT NEXTVAL ('TBL_CITY_LANG_SEQ') NOT NULL,
CITY_NAME VARCHAR(150) NOT NULL,
CITY_ID BIGINT NOT NULL,
LANGUAGE_ID BIGINT NOT NULL,
DB_EDIT_DATE TIMESTAMP(3) NOT NULL,
DB_USER_ID BIGINT NOT NULL,
DB_STATUS_ID INT NOT NULL,
CONSTRAINT PK_TBL_CITY_LANG_SEQ PRIMARY KEY
(
ID
),
CONSTRAINT IX_TBL_CITY_LANG_SEQ UNIQUE
(
LANGUAGE_ID,
CITY_ID
));
和 sequelize upsert 用法:
cityTable.upsert(myjson).then(function (result) {
resolve(result);
});
SQL 执行日志为:
CREATE OR REPLACE FUNCTION pg_temp.sequelize_upsert() RETURNS integer AS $func$
BEGIN INSERT INTO "tbl_city_lang" ("id","city_name","city_id","language_id","db_edit_date","db_user_id","db_status_id") VALUES (1,'istanbul 1','19','1','2015-03-03','2','1');
RETURN 1;
EXCEPTION WHEN unique_violation
THEN UPDATE "tbl_city_lang" SET "id"=1,"city_name"='istanbul 1',"city_id"='19',"language_id"='1',"db_edit_date"='2015-03-03',"db_user_id"='2',"db_status_id"='1' WHERE (("id" IS NULL AND "city_id" = '19')); RETURN 2;
END;
$func$ LANGUAGE plpgsql;
SELECT * FROM pg_temp.sequelize_upsert();
不报错也不更新。我认为问题出在脚本的 where 条件。但是 table 应该有主键,但是 updatable 应该有唯一的约束。
WHERE (("id" IS NULL AND "city_id" = '19'))
但是 table 应该有主键但是 updatable 由唯一约束。
此问题源于sequelize-auto。我编辑了源代码。
在lib/dialects/index.js里面编辑
发件人:
return 'SELECT \
o.conname AS constraint_name, \
(SELECT nspname FROM pg_namespace WHERE oid=m.relnamespace) AS source_schema, \
m.relname AS source_table, \
(SELECT a.attname FROM pg_attribute a WHERE a.attrelid = m.oid AND a.attnum = o.conkey[1] AND a.attisdropped = false) AS source_column, \
(SELECT nspname FROM pg_namespace WHERE oid=f.relnamespace) AS target_schema, \
f.relname AS target_table, \
(SELECT a.attname FROM pg_attribute a WHERE a.attrelid = f.oid AND a.attnum = o.confkey[1] AND a.attisdropped = false) AS target_column, \
o.contype, \
(SELECT d.adsrc AS extra FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_attrdef d ON (a.attrelid, a.attnum) = (d.adrelid, d.adnum) \ WHERE NOT a.attisdropped AND a.attnum > 0 AND a.attrelid = o.conrelid \ LIMIT 1) \
FROM pg_constraint o \
LEFT JOIN pg_class c ON c.oid = o.conrelid \
LEFT JOIN pg_class f ON f.oid = o.confrelid \
LEFT JOIN pg_class m ON m.oid = o.conrelid \
WHERE o.conrelid = (SELECT oid FROM pg_class WHERE relname = \'' + tableName + '\' LIMIT 1)'
收件人:
SELECT \
o.conname AS constraint_name, \
(SELECT nspname FROM pg_namespace WHERE oid=m.relnamespace) AS source_schema, \
m.relname AS source_table, \
pga.attname AS source_column, \
(SELECT nspname FROM pg_namespace WHERE oid=f.relnamespace) AS target_schema, \
f.relname AS target_table, \
(SELECT a.attname FROM pg_attribute a WHERE a.attrelid = f.oid AND a.attnum = o.confkey[1] AND a.attisdropped = false) AS target_column, \
o.contype, \
(SELECT d.adsrc AS extra FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_attrdef d ON (a.attrelid, a.attnum) = (d.adrelid, d.adnum) \ WHERE NOT a.attisdropped AND a.attnum > 0 AND a.attrelid = o.conrelid \ LIMIT 1) \
FROM pg_constraint o \
LEFT JOIN pg_attribute pga ON pga.attrelid = o.conindid \
LEFT JOIN pg_class c ON c.oid = o.conrelid \
LEFT JOIN pg_class f ON f.oid = o.confrelid \
LEFT JOIN pg_class m ON m.oid = o.conrelid \
WHERE o.conrelid = (SELECT oid FROM pg_class WHERE relname = \'' + tableName + '\' LIMIT 1)'
编辑里面lib/index.js
发件人:
else if (attr === "primaryKey") {
if (self.tables[table][field][attr] === true && (! _.has(self.tables[table][field], 'foreignKey') || (_.has(self.tables[table][field], 'foreignKey') && !! self.tables[table][field].foreignKey.isPrimaryKey)))
text[table] += spaces + spaces + spaces + "primaryKey: true";
else return true
}
收件人:
else if (attr === "primaryKey") {
if (self.tables[table][field][attr] === true && self.tables[table][field].foreignKey.contype == 'u' )
text[table] += spaces + spaces + spaces + "unique: '" + self.tables[table][field].foreignKey.constraint_name + "'";
if (self.tables[table][field][attr] === true && (! _.has(self.tables[table][field], 'foreignKey') || (_.has(self.tables[table][field], 'foreignKey') && !! self.tables[table][field].foreignKey.isPrimaryKey)))
text[table] += spaces + spaces + spaces + "primaryKey: true";
else return true
}
重新生成模型和作品。
我正在尝试将 sequelize js 的 upsert 方法与 postgresql 一起使用。我正在通过 sequelize-auto js
生成模型我的 table 就像:
CREATE SEQUENCE TBL_CITY_LANG_SEQ;
CREATE TABLE TBL_CITY_LANG(
ID BIGINT DEFAULT NEXTVAL ('TBL_CITY_LANG_SEQ') NOT NULL,
CITY_NAME VARCHAR(150) NOT NULL,
CITY_ID BIGINT NOT NULL,
LANGUAGE_ID BIGINT NOT NULL,
DB_EDIT_DATE TIMESTAMP(3) NOT NULL,
DB_USER_ID BIGINT NOT NULL,
DB_STATUS_ID INT NOT NULL,
CONSTRAINT PK_TBL_CITY_LANG_SEQ PRIMARY KEY
(
ID
),
CONSTRAINT IX_TBL_CITY_LANG_SEQ UNIQUE
(
LANGUAGE_ID,
CITY_ID
));
和 sequelize upsert 用法:
cityTable.upsert(myjson).then(function (result) {
resolve(result);
});
SQL 执行日志为:
CREATE OR REPLACE FUNCTION pg_temp.sequelize_upsert() RETURNS integer AS $func$
BEGIN INSERT INTO "tbl_city_lang" ("id","city_name","city_id","language_id","db_edit_date","db_user_id","db_status_id") VALUES (1,'istanbul 1','19','1','2015-03-03','2','1');
RETURN 1;
EXCEPTION WHEN unique_violation
THEN UPDATE "tbl_city_lang" SET "id"=1,"city_name"='istanbul 1',"city_id"='19',"language_id"='1',"db_edit_date"='2015-03-03',"db_user_id"='2',"db_status_id"='1' WHERE (("id" IS NULL AND "city_id" = '19')); RETURN 2;
END;
$func$ LANGUAGE plpgsql;
SELECT * FROM pg_temp.sequelize_upsert();
不报错也不更新。我认为问题出在脚本的 where 条件。但是 table 应该有主键,但是 updatable 应该有唯一的约束。
WHERE (("id" IS NULL AND "city_id" = '19'))
但是 table 应该有主键但是 updatable 由唯一约束。
此问题源于sequelize-auto。我编辑了源代码。
在lib/dialects/index.js里面编辑
发件人:
return 'SELECT \
o.conname AS constraint_name, \
(SELECT nspname FROM pg_namespace WHERE oid=m.relnamespace) AS source_schema, \
m.relname AS source_table, \
(SELECT a.attname FROM pg_attribute a WHERE a.attrelid = m.oid AND a.attnum = o.conkey[1] AND a.attisdropped = false) AS source_column, \
(SELECT nspname FROM pg_namespace WHERE oid=f.relnamespace) AS target_schema, \
f.relname AS target_table, \
(SELECT a.attname FROM pg_attribute a WHERE a.attrelid = f.oid AND a.attnum = o.confkey[1] AND a.attisdropped = false) AS target_column, \
o.contype, \
(SELECT d.adsrc AS extra FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_attrdef d ON (a.attrelid, a.attnum) = (d.adrelid, d.adnum) \ WHERE NOT a.attisdropped AND a.attnum > 0 AND a.attrelid = o.conrelid \ LIMIT 1) \
FROM pg_constraint o \
LEFT JOIN pg_class c ON c.oid = o.conrelid \
LEFT JOIN pg_class f ON f.oid = o.confrelid \
LEFT JOIN pg_class m ON m.oid = o.conrelid \
WHERE o.conrelid = (SELECT oid FROM pg_class WHERE relname = \'' + tableName + '\' LIMIT 1)'
收件人:
SELECT \
o.conname AS constraint_name, \
(SELECT nspname FROM pg_namespace WHERE oid=m.relnamespace) AS source_schema, \
m.relname AS source_table, \
pga.attname AS source_column, \
(SELECT nspname FROM pg_namespace WHERE oid=f.relnamespace) AS target_schema, \
f.relname AS target_table, \
(SELECT a.attname FROM pg_attribute a WHERE a.attrelid = f.oid AND a.attnum = o.confkey[1] AND a.attisdropped = false) AS target_column, \
o.contype, \
(SELECT d.adsrc AS extra FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_attrdef d ON (a.attrelid, a.attnum) = (d.adrelid, d.adnum) \ WHERE NOT a.attisdropped AND a.attnum > 0 AND a.attrelid = o.conrelid \ LIMIT 1) \
FROM pg_constraint o \
LEFT JOIN pg_attribute pga ON pga.attrelid = o.conindid \
LEFT JOIN pg_class c ON c.oid = o.conrelid \
LEFT JOIN pg_class f ON f.oid = o.confrelid \
LEFT JOIN pg_class m ON m.oid = o.conrelid \
WHERE o.conrelid = (SELECT oid FROM pg_class WHERE relname = \'' + tableName + '\' LIMIT 1)'
编辑里面lib/index.js
发件人:
else if (attr === "primaryKey") {
if (self.tables[table][field][attr] === true && (! _.has(self.tables[table][field], 'foreignKey') || (_.has(self.tables[table][field], 'foreignKey') && !! self.tables[table][field].foreignKey.isPrimaryKey)))
text[table] += spaces + spaces + spaces + "primaryKey: true";
else return true
}
收件人:
else if (attr === "primaryKey") {
if (self.tables[table][field][attr] === true && self.tables[table][field].foreignKey.contype == 'u' )
text[table] += spaces + spaces + spaces + "unique: '" + self.tables[table][field].foreignKey.constraint_name + "'";
if (self.tables[table][field][attr] === true && (! _.has(self.tables[table][field], 'foreignKey') || (_.has(self.tables[table][field], 'foreignKey') && !! self.tables[table][field].foreignKey.isPrimaryKey)))
text[table] += spaces + spaces + spaces + "primaryKey: true";
else return true
}
重新生成模型和作品。