В настоящее время я создаю приложение с использованием инфраструктуры KnexJS, которая помогает мне писать sqlite3 в разработке и postgresql в производстве (для Heroku).
Моя основная проблема заключается в том, что мое приложение отлично работает, когда на моей машине, но как только я загружаю его в герою, он ломается. В журналах Heroku я получаю сообщение:
{ error: insert into "contracts" ("contract_desc", "contract_header", "owner_id", "signee_id") values ($1, $2, $3, $4) - duplicate key value violates unique constraint "contracts_pkey"
И это не позволяет мне вставлять данные в мою базу данных.
Мои миграции Knex для таблицы настраиваются следующим образом:
exports.up = function(knex, Promise) {
return knex.schema.createTable('contracts', function (table) {
table.increments('id').primary()
table.integer('owner_id')
table.integer('signee_id')
table.string('contract_header')
table.text('contract_desc')
table.string('signature_url')
table.string('date_signed')
table.boolean('isSigned')
})
};
exports.down = function(knex, Promise) {
return knex.schema.dropTable('contracts')
};
И функция, которую я вызываю для вставки данных, выглядит так:
function newContract (id, contractDetails) {
return knex('contracts')
.select('owner_id', 'signee_id', 'contract_header', 'contract_desc')
.insert({
owner_id: id,
signee_id: contractDetails.signee_id,
contract_header: contractDetails.contract_header,
contract_desc:contractDetails.contract_desc
})
}
Любые идеи о том, что может быть причиной этого?
Хорошо, я понял.
Попробуйте удалить поля id
из вашего семени.
Позвольте мне объяснить, почему это происходит
Поля автогенерации Postgres принимают свои значения из последовательностей
Вы можете попробовать команду \d <table_name>
в интерфейсе psql
. Это даст вам что-то вроде
...
id | bigint | not null default nextval('<table_name>_id_seq'::regclass)
...
При выполнении
insert into table_name (name) values ('Kappa')
Вы фактически опускаете поле id
и вставляете значение по умолчанию, которое является nextval('<table_name>_id_seq')
.
Указав явно ваш параметр id
в запросе, вы не используете эту функцию, и в следующий раз, когда вы его используете, вы можете получить столкновение идентификаторов. Вы вставили id = 1
и nextval
сгенерировали 1
.
select * from contracts
и из contract_id_seqselect * from contracts_id_seq
Это явно вызвано тем, что у вас есть конфликты в столбцеcontacts.id
(при попытке дважды вставить одно и то же значение в столбец первичного ключа). Трудно сказать, что именно произошло. И вам не нужно.select(...)
. Построитель выводит тот же запрос без.select
. И какую версию узла / knex вы используете?{id: 1, fName: 'Todd', lName: 'Drinkwater', organisation: 'TDD', email: '[email protected]'}
gmail.com'}, {id: 2, fName: 'Blair', lName: 'Drinkwater', organisation: 'BDD', email: '[email protected]'}gmail.com'}