Primary Key not respected, Sequelize tries to insert into id field
See original GitHub issueIssue Description
I am trying to use a string as the primary key for one of my tables instead of id
, but on create
Sequelize always tries to insert a default id
, which crashes.
What are you doing?
The relevant piece of my config.json
:
{
"development": {
"username": null,
"password": null,
"database": "experiment",
"host": "127.0.0.1",
"dialect": "postgres"
}
}
After initializing the project, I ran npx sequelize-cli models:generate --name Foo --attributes foo:string,bar:string,quux:integer
and edited the migrations/...-create-foo.js
file as such:
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('Foos', {
foo: {
allowNull: false,
autoIncrement: false,
primaryKey: true,
type: Sequelize.STRING
},
bar: {
type: Sequelize.STRING
},
quux: {
type: Sequelize.INTEGER
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('Foos');
}
};
Small test script:
const db = require('./models/index.js');
const Foo = db.Foo;
Foo.create({ foo: "Foo", bar: "Bar", quux: 42 }).then(() => console.log("It worked!"));
What do you expect to happen?
I expect the record to get created and log It worked!
.
What is actually happening?
Sequelize tries to insert a default id
, which isn’t present in the table.
Executing (default): INSERT INTO "Foos" ("id","foo","bar","quux","createdAt","updatedAt") VALUES (DEFAULT,$1,$2,$3,$4,$5) RETURNING *;
Unhandled rejection SequelizeDatabaseError: column "id" of relation "Foos" does not exist
at Query.formatError (/Users/Mitch/sequelize/sequelize-bug/node_modules/sequelize/lib/dialects/postgres/query.js:366:16)
at query.catch.err (/Users/Mitch/sequelize/sequelize-bug/node_modules/sequelize/lib/dialects/postgres/query.js:72:18)
at tryCatcher (/Users/Mitch/sequelize/sequelize-bug/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/Users/Mitch/sequelize/sequelize-bug/node_modules/bluebird/js/release/promise.js:547:31)
at Promise._settlePromise (/Users/Mitch/sequelize/sequelize-bug/node_modules/bluebird/js/release/promise.js:604:18)
at Promise._settlePromise0 (/Users/Mitch/sequelize/sequelize-bug/node_modules/bluebird/js/release/promise.js:649:10)
at Promise._settlePromises (/Users/Mitch/sequelize/sequelize-bug/node_modules/bluebird/js/release/promise.js:725:18)
at _drainQueueStep (/Users/Mitch/sequelize/sequelize-bug/node_modules/bluebird/js/release/async.js:93:12)
at _drainQueue (/Users/Mitch/sequelize/sequelize-bug/node_modules/bluebird/js/release/async.js:86:9)
at Async._drainQueues (/Users/Mitch/sequelize/sequelize-bug/node_modules/bluebird/js/release/async.js:102:5)
at Immediate.Async.drainQueues [as _onImmediate] (/Users/Mitch/sequelize/sequelize-bug/node_modules/bluebird/js/release/async.js:15:14)
at runCallback (timers.js:705:18)
at tryOnImmediate (timers.js:676:5)
at processImmediate (timers.js:658:5)
Additional context
The table looks like I would expect it to, without an id
field and with a primary key on foo
.
Additional note: if I rename foo
to id
, it works. I don’t think, however, that the user should be restricted to naming the primary key id
, especially since that’s not a restriction that psql
enforces (or any other dialect, as far as I know . . . ?).
Environment
- Sequelize version: 5.21.2
- Node.js version: 10.16.3
- Operating System: macOS Mojave 10.14.5
Issue Template Checklist
How does this problem relate to dialects?
- I don’t know, I was using Postgres, with connector library version pg@7.21.1 and database version PostgreSQL 11.3
Would you be willing to resolve this issue by submitting a Pull Request?
- Yes, I have the time but I don’t know how to start, I would need (a very small amount of) guidance. --> a good starting point would help
Issue Analytics
- State:
- Created 4 years ago
- Reactions:4
- Comments:16 (3 by maintainers)
Maybe this can help (extracted from the docs)
Primary keys Sequelize will assume your table has a id primary key property by default.
To define your own primary key:
class Collection extends Model {} Collection.init({ uid: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true // Automatically gets converted to SERIAL for postgres } }, { sequelize });
class Collection extends Model {} Collection.init({ uuid: { type: DataTypes.UUID, primaryKey: true } }, { sequelize }); And if your model has no primary key at all you can use Model.removeAttribute(‘id’);
You’re right, I think it is 😃 Until the feature is released, it’s also possible to do
Foo.removeAttribute('id')
to remove the auto-generated primary key