重复的键值违反了Postgres,Knex和Promises的唯一约束

时间:2018-12-03 07:32:03

标签: postgresql knex.js

我有一个很奇怪的问题。当我在具有唯一ID的“存储库”表中插入五个角色时,以下错误多次出现(提到相同ID!)。我没有为PK使用自动增量。

Error saving repo { error: duplicate key value violates unique constraint "repository_pkey"
    at Connection.parseE (/Users/macintosh/node-projects/risingstack/node_modules/pg/lib/connection.js:554:11)
    at Connection.parseMessage (/Users/macintosh/node-projects/risingstack/node_modules/pg/lib/connection.js:379:19)
    at Socket.<anonymous> (/Users/macintosh/node-projects/risingstack/node_modules/pg/lib/connection.js:119:22)
    at emitOne (events.js:116:13)
    at Socket.emit (events.js:211:7)
    at addChunk (_stream_readable.js:263:12)
    at readableAddChunk (_stream_readable.js:250:11)
    at Socket.Readable.push (_stream_readable.js:208:10)
    at TCP.onread (net.js:601:20)
  name: 'error',
  length: 202,
  severity: 'ERROR',
  code: '23505',
  detail: 'Key (id)=(80073079) already exists.',
  hint: undefined,
  position: undefined,
  internalPosition: undefined,
  internalQuery: undefined,
  where: undefined,
  schema: 'public',
  table: 'repository',
  column: undefined,
  dataType: undefined,
  constraint: 'repository_pkey',
  file: 'nbtinsert.c',
  line: '434',
  routine: '_bt_check_unique' } 

knex生成的Postgres代码:

insert into "repository" ("description", "full_name", "html_url", "id", "language", "owner_id", "stargazers_count") values ('Node.js JavaScript runtime :sparkles::turtle::rocket::sparkles:', 'nodejs/node', 'https://github.com/nodejs/node', 27193779, 'JavaScript', 9950313, 56009)

insert into "repository" ("description", "full_name", "html_url", "id", "language", "owner_id", "stargazers_count") values (':closed_book:《Node.js 包教不包会》 by alsotang', 'alsotang/node-lessons', 'https://github.com/alsotang/node-lessons', 24812854, 'JavaScript', 1147375, 13989)

insert into "repository" ("description", "full_name", "html_url", "id", "language", "owner_id", "stargazers_count") values ('Node.js based forum software built for the modern web', 'NodeBB/NodeBB', 'https://github.com/NodeBB/NodeBB', 9603889, 'JavaScript', 4449608, 9399)

insert into "repository" ("description", "full_name", "html_url", "id", "language", "owner_id", "stargazers_count") values (':baby_chick:Nodeclub 是使用 Node.js 和 MongoDB 开发的社区系统', 'cnodejs/nodeclub', 'https://github.com/cnodejs/nodeclub', 3447593, 'JavaScript', 1455983, 7907)

insert into "repository" ("description", "full_name", "html_url", "id", "language", "owner_id", "stargazers_count") values ('Mysterium Node - VPN server and client for Mysterium Network', 'mysteriumnetwork/node', 'https://github.com/mysteriumnetwork/node', 80073079, 'Go', 23056638, 478)

存储库的Knex模式:

  return knex.schema.createTable('repository', (table) => {
    table.integer('id').primary();
    table.integer('owner_id');
    table.foreign('owner_id').references('user.id').onDelete('CASCADE').onUpdate('CASCADE');
    table.string('full_name');
    table.string('description');
    table.string('html_url');
    table.string('language');
    table.integer('stargazers_count');
  })

运行代码以插入存储库:

  const fn = composeMany(withOwner, removeIrrelevantProperties, defaultLanguageAndDescToString, saveAndPublish);
  const tRepos = r.map(fn);
  return Promise.all(tRepos);

const saveAndPublish = (r) => {
  return User
    .insert(r.owner)
    .catch(e => console.log('Error saving User', e))
    .then(() => {
      const { owner, ...repo } = r;
      const q = Repository.insert(repo);
      console.log(q.toQuery());
      return q;
    })
    .catch(e => {
      console.log('Error saving repo', e)}
    );

1 个答案:

答案 0 :(得分:0)

类似您的数据库的声音已经插入了带有主键id == 80073079的行。

为了确保这一点,请在插入之前尝试使用该键查询数据库行。我只是想知道这些id是如何生成的,因为您显然没有使用id序列。

获取ID的输入数据可能已损坏并且具有重复的id