1

node-postgresを使用して 2 つのパラメーター化された挿入クエリを実行しようとしています。1 つ目は主キー列を指定し、2 つ目は指定しません。

2 番目のクエリは、主キー列を指定していませんが、主キーが重複していると言って失敗します。

私のpgテーブル:

CREATE TABLE teams (
  id serial PRIMARY KEY,
  created_by int REFERENCES users,
  name text,
  logo text
);

この問題を再現するコード:

var pg = require('pg');

var insertWithId = 'INSERT INTO teams(id, name, created_by) VALUES($1, $2, $3) RETURNING id';
var insertWithoutId = 'INSERT INTO teams(name, created_by) VALUES($1, $2) RETURNING id';

pg.connect(process.env.POSTGRES_URI, function (err, client, releaseClient) {
  client.query(insertWithId, [1, 'First Team', 1], function (err, result) {
    releaseClient();

    if (err) {
      throw err;
    }

    console.log('first team created');
  });
});

pg.connect(process.env.POSTGRES_URI, function (err, client, releaseClient) {
  client.query(insertWithoutId, ['Second Team', 1], function (err, result) {
    releaseClient();

    if (err) {
      console.log(err);
    }
  });
});

そして、これを実行した出力:

first team created

{ [error: duplicate key value violates unique constraint "teams_pkey"]
  name: 'error',
  length: 173,
  severity: 'ERROR',
  code: '23505',
  detail: 'Key (id)=(1) already exists.',
  hint: undefined,
  position: undefined,
  internalPosition: undefined,
  internalQuery: undefined,
  where: undefined,
  schema: 'public',
  table: 'teams',
  column: undefined,
  dataType: undefined,
  constraint: 'teams_pkey',
  file: 'nbtinsert.c',
  line: '406',
  routine: '_bt_check_unique' }

ソースを読んで収集したことにnode-postgresよると、パラメーター化されたクエリは準備済みクエリとして扱われ、nameパラメーターを再利用するとキャッシュされます。ソースを掘り下げてみると、私のクエリに name プロパティがあるとは思えません。

これを回避する方法について誰かアイデアがありますか?

4

1 に答える 1

1

最初の挿入は の値を提供するidため、シリアルはインクリメントされません。最初の挿入後、シリアルはまだ 1 です。2 番目の挿入ではの値が提供されないidため、シリアル (=1) が使用されます。これは重複しています。最善の解決策は、2 番目のステートメントのみを使用し、必要に応じて返された ID をアプリケーションに使用させることです。

要するに、シリアルに干渉しないでください。


シーケンスの次の値を修正する必要がある場合は、次のステートメントのようなものを使用できます。

SELECT setval('teams_id_seq', (SELECT MAX(id) FROM teams) )
        ;
于 2015-07-18T11:46:02.553 に答える