javascript - Sequelize js upsert 控制主键是否为空

标签 javascript node.js postgresql sequelize.js upsert

我正在尝试使用 postgresql 对 js 进行 Sequelize 的 upsert 方法。我正在通过 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
));

并续写 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 条件。但是该表应该具有主键,但可以通过唯一约束进行更新。

WHERE (("id" IS NULL AND "city_id" = '19'))



但是该表应该有主键,但可以通过唯一约束更新。

最佳答案

这个问题源自 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
          }

重新生成模型和作品。

关于javascript - Sequelize js upsert 控制主键是否为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40850186/

相关文章:

javascript - 当自调用函数可以访问JavaScript中的全局变量时,将全局变量传递给自调用函数的目的是什么?

javascript - 通过带引号的 Javascript 字符串传递变量

node.js - Node JS : How to set template engine in krakenjs

javascript - 如何在 KOA 2 中编写异步中间件

node.js - 为什么我的 header 没有在重定向时设置?

python - 当 Pyramid 在 CherryPy 之上处理 HTTP 请求时打开了多少数据库连接

javascript - 如何以特殊分割方式重复背景图

php - 为什么我的 php 变量没有通过 javascript 警报输出?

ruby-on-rails - 事件记录 : get all dates in multiple ranges

ruby-on-rails - 在 ID 存在时获取 "Unknown primary key for table"