Я пытаюсь запустить два параметризованных запроса на вставку, используя node-postgres: первый указывает основной ключевой столбец, второй - нет.
Второй запрос, даже если не указывает столбец первичного ключа, не может сказать, что существует дублированный первичный ключ.
Моя таблица 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.
Есть ли у кого-нибудь идеи, как этого можно избежать?
id
, поэтому серийный номер не увеличивается. Серийный номер по-прежнему1
. Вторая вставка не предоставляет значение дляid
, поэтому используется серийный номер (= 1). Это дубликат. Лучшее решение - использовать только второй оператор и позволить приложению использовать возвращенныйid
, если необходимо. - person wildplasser   schedule 18.07.2015