Sequelize: Many-To-Many relation between MariaDB and Postgres - postgresql

Little Background Story
Here is my scenario, I have a database named Location in my MariaDB, and I have a User database in my Postgres. I want to chain two of them in my Postgres DB. So I have two tables users and userLocations. Oh yeah, a nice thing to note is that I only have access to read (SELECT and CREATE VIEW) from LocationDB, and connecting to UserDB as root. Yes I have successfully authenticate() both of them. I even able to receive data from LocationDB however the only problem right now is creating that relation between User and Location. Error logs available on the bottom.
Here is my models:
models/user.js
// ... Connection to UserDB (uses Postgres)
const UserDB = require('../datasources/user-db')
const User = UserDB.define('user', {
id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true },
name: { type: Sequelize.STRING, allowNull: false }
})
module.exports = User
models/location.js
// Connection to LocationDB (uses MariaDB)
const LocationDB = require('../datasources/location-db')
const Location = LocationDB.define('ms_location', {
id_Location: { type: Sequelize.INTEGER, primaryKey: true },
name_Location: { type: Sequelize.STRING, allowNull: false }
}, { timestamps: false, freezeTableName: true })
module.exports = Location
models/user-location.js
// ... Connection to UserDB (uses Postgres)
const UserDB = require('../datasources/user-db')
const UserLocation = UserDB.define('userLocation', {
id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true }
})
module.exports = UserLocation
app.js
const Location = require('./models/location')
const User = require('./models/user')
const UserLocation = require('./models/user-location')
User.belongsToMany(Location, { through: UserLocation })
This is a minified version of the case, if you need more information please do ask as I am still new to sequelize as well
The error log: (sorry I don't have any idea to beautify it)
{ SequelizeDatabaseError: relation "ms_location" does not exist
at Query.formatError (<path-to-project>/node_modules/.registry.npmjs.org/sequelize/5.8.6/node_modules/sequelize/lib/dialects/postgres/query.js:354:16)
at query.catch.err (<path-to-project>/node_modules/.registry.npmjs.org/sequelize/5.8.6/node_modules/sequelize/lib/dialects/postgres/query.js:71:18)
at tryCatcher (<path-to-project>/node_modules/.registry.npmjs.org/bluebird/3.5.5/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (<path-to-project>/node_modules/.registry.npmjs.org/bluebird/3.5.5/node_modules/bluebird/js/release/promise.js:517:31)
at Promise._settlePromise (<path-to-project>/node_modules/.registry.npmjs.org/bluebird/3.5.5/node_modules/bluebird/js/release/promise.js:574:18)
at Promise._settlePromise0 (<path-to-project>/node_modules/.registry.npmjs.org/bluebird/3.5.5/node_modules/bluebird/js/release/promise.js:619:10)
at Promise._settlePromises (<path-to-project>/node_modules/.registry.npmjs.org/bluebird/3.5.5/node_modules/bluebird/js/release/promise.js:695:18)
at _drainQueueStep (<path-to-project>/node_modules/.registry.npmjs.org/bluebird/3.5.5/node_modules/bluebird/js/release/async.js:138:12)
at _drainQueue (<path-to-project>/node_modules/.registry.npmjs.org/bluebird/3.5.5/node_modules/bluebird/js/release/async.js:131:9)
at Async._drainQueues (<path-to-project>/node_modules/.registry.npmjs.org/bluebird/3.5.5/node_modules/bluebird/js/release/async.js:147:5)
at Immediate.Async.drainQueues [as _onImmediate] (<path-to-project>/node_modules/.registry.npmjs.org/bluebird/3.5.5/node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:705:18)
at tryOnImmediate (timers.js:676:5)
at processImmediate (timers.js:658:5)
name: 'SequelizeDatabaseError',
parent:
{ error: relation "ms_location" does not exist
at Connection.parseE (<path-to-project>/node_modules/.registry.npmjs.org/pg/7.11.0/node_modules/pg/lib/connection.js:602:11)
at Connection.parseMessage (<path-to-project>/node_modules/.registry.npmjs.org/pg/7.11.0/node_modules/pg/lib/connection.js:399:19)
at Socket.<anonymous> (<path-to-project>/node_modules/.registry.npmjs.org/pg/7.11.0/node_modules/pg/lib/connection.js:121:22)
at Socket.emit (events.js:189:13)
at addChunk (_stream_readable.js:284:12)
at readableAddChunk (_stream_readable.js:265:11)
at Socket.Readable.push (_stream_readable.js:220:10)
at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
name: 'error',
length: 107,
severity: 'ERROR',
code: '42P01',
detail: undefined,
hint: undefined,
position: undefined,
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: undefined,
table: undefined,
column: undefined,
dataType: undefined,
constraint: undefined,
file: 'namespace.c',
line: '426',
routine: 'RangeVarGetRelidExtended',
sql:
'CREATE TABLE IF NOT EXISTS "userLocations" ("id" SERIAL , "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" INTEGER REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE, "msLocationIdLocation" INTEGER REFERENCES "ms_location" ("id_Location") ON DELETE CASCADE ON UPDATE CASCADE, UNIQUE ("userId", "msLocationIdLocation"), PRIMARY KEY ("id"));' },
original:
{ error: relation "ms_location" does not exist
at Connection.parseE (<path-to-project>/node_modules/.registry.npmjs.org/pg/7.11.0/node_modules/pg/lib/connection.js:602:11)
at Connection.parseMessage (<path-to-project>/node_modules/.registry.npmjs.org/pg/7.11.0/node_modules/pg/lib/connection.js:399:19)
at Socket.<anonymous> (<path-to-project>/node_modules/.registry.npmjs.org/pg/7.11.0/node_modules/pg/lib/connection.js:121:22)
at Socket.emit (events.js:189:13)
at addChunk (_stream_readable.js:284:12)
at readableAddChunk (_stream_readable.js:265:11)
at Socket.Readable.push (_stream_readable.js:220:10)
at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
name: 'error',
length: 107,
severity: 'ERROR',
code: '42P01',
detail: undefined,
hint: undefined,
position: undefined,
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: undefined,
table: undefined,
column: undefined,
dataType: undefined,
constraint: undefined,
file: 'namespace.c',
line: '426',
routine: 'RangeVarGetRelidExtended',
sql:
'CREATE TABLE IF NOT EXISTS "userLocations" ("id" SERIAL , "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" INTEGER REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE, "msLocationIdLocation" INTEGER REFERENCES "ms_location" ("id_Location") ON DELETE CASCADE ON UPDATE CASCADE, UNIQUE ("userId", "msLocationIdLocation"), PRIMARY KEY ("id"));' },
sql:
'CREATE TABLE IF NOT EXISTS "userLocations" ("id" SERIAL , "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" INTEGER REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE, "msLocationIdLocation" INTEGER REFERENCES "ms_location" ("id_Location") ON DELETE CASCADE ON UPDATE CASCADE, UNIQUE ("userId", "msLocationIdLocation"), PRIMARY KEY ("id"));' }

You've told Sequelize that you have a table called user and a table called msLocation and that the two are related through another table called userLocation. (Or is it userLocations? Your code and error message are inconsistent.)
It looks like Sequelize is trying to create the userLocations table UserDB but it's failing because as part of the table definition, it's trying to create a foreign key reference to ms_location:
"msLocationIdLocation" INTEGER REFERENCES "ms_location" ("id_Location")
ON DELETE CASCADE ON UPDATE CASCADE
which fails because ms_location is not in the UserDB but rather in the other database.
I don't know if Sequelize can actually handle tables spanning multiple databases servers, but I doubt it. Creating a query that spans two tables in the same database is easy, Sequelize can just create a join. It's a totally different story if the tables are on two different servers; now Sequelize would have to run two different queries and do all the join logic in memory. That's a pretty big lift.
Some databases have a way to create a table in one database that replicates or forwards to a table in another database. If PostgreSQL supports that, you could try using that to replicate or shadow the MariaDB table, which would enable Sequelize to see all the tables as being part of UserDB.

Related

Does the EFCore migration locks entire schema?

In our project, we handle DB (Postgres) migrations using EFCore migrations (but we write them ourselves, they are not autogenerated). Example script:
// it is making column nullable
migrationBuilder.AlterColumn<string>(
name: "discount_type",
table: some_table_name,
nullable: true,
schema: "some_schema");
// it is making column nullable
migrationBuilder.AlterColumn<decimal>(
name: "discount_value",
table: some_table_name,
nullable: true,
schema: "some_schema");
migrationBuilder.AddForeignKey(
name: "some_key_name_fk",
table: some_table_name,
column: "code_id",
schema: "some_schema",
principalTable: some_table_name_2,
principalColumn: "id",
principalSchema: "some_schema",
onDelete: ReferentialAction.Restrict);
migrationBuilder.DropColumn(
name: "description_english",
table: some_table_name,
schema: Constants.Schema);
migrationBuilder.DropColumn(
name: "description_german",
table: some_table_name,
schema: "some_schema");
We found that during the migration, our service become unresponsive for few minutes. All queries (SELECT queries in majority) where giving timeout. 100% requests failed. Please note that some_table_name table has over 120 million records.
My question is if EFCore migration somehow locks the entire DB schema, even preventing it from reading data? If 'yes' - how to prevent it?

Cannot make work loopback 4 todo-list tutorial with connection to PostgreSQL

I am doing tutorials in the loopback documentation by I have a problem at the last stage of the todo-list tutorial, when I want to connect the app to a database (PostgreSQL, as in the tutorial).
I have initialized the application by doing lb4 example todo-list and then I have followed instructions given at https://loopback.io/doc/en/lb4/todo-list-tutorial-sqldb.html.
I did not forget to do npm run migrate -- --rebuild, tables are well created in the database. Tables are empty.
When I POST /todo-lists (using http://localhost:3000/explorer/#/TodoListController/TodoListController.create) with this body
{ "title": "grocery list" }
I get the answer
{
"error": {
"statusCode": 500,
"message": "Internal Server Error"
}
}
And I have this log in the console
npm start
...
Server is running at http://[::1]:3000
Request POST /todo-lists failed with status code 500. error: null value in column "id" of relation "todolist" violates not-null constraint
at Parser.parseErrorMessage (C:\Users\azias\Documents\dev\js\loopback4-example-todo-list\node_modules\pg-protocol\dist\parser.js:278:15)
at Parser.handlePacket (C:\Users\azias\Documents\dev\js\loopback4-example-todo-list\node_modules\pg-protocol\dist\parser.js:126:29)
at Parser.parse (C:\Users\azias\Documents\dev\js\loopback4-example-todo-list\node_modules\pg-protocol\dist\parser.js:39:38)
at Socket.stream.on (C:\Users\azias\Documents\dev\js\loopback4-example-todo-list\node_modules\pg-protocol\dist\index.js:10:42)
at Socket.emit (events.js:198:13)
at addChunk (_stream_readable.js:288:12)
at readableAddChunk (_stream_readable.js:269:11)
at Socket.Readable.push (_stream_readable.js:224:10)
at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
As I understand the mentioned id is not automatically generated (I suppose it should be) and so is missing.
I am discovering loopback so I do not know what I have to change to make it works.
I think I have finally found.
In all models, the id was defined as property with the setting generated: false, it has to be changed to generated: true. This make sequences to be generated in the database and the id automatically generated.
For example, in todo-list.model.ts, the code
#property({
type: 'number',
id: true,
generated: false,
})
id?: number;
has to be changed to
#property({
type: 'number',
id: true,
generated: true,
})
id?: number;
(same in todo-list-image.model.ts and todo.model.ts)

Knex cannot find table in Cloud SQL Postgres from Cloud Functions

I am trying to connect to a Postgres 12 DB running in Cloud SQL from a Cloud Function written in TypeScript.
I create the database with the following:
import * as Knex from "knex"
const { username, password, instance } = ... // username, password, connection name (<app-name>:<region>:<database>)
const config = {
client: 'pg',
connection: {
user: username,
password: password,
database: 'ingredients',
host: `/cloudsql/${instance}`,
pool: { min: 1, max: 1}
}
}
const knex = Knex(config as Knex.Config)
I am then querying the database using:
const query = ... // passed in as param
const result = await knex('tableName').where('name', 'ilike', query).select('*')
When I run this code, I get the following error in the Cloud Functions logs:
Unhandled error { error: select * from "tableName" where "name" ilike $1 - relation "tableName" does not exist
at Parser.parseErrorMessage (/workspace/node_modules/pg-protocol/dist/parser.js:278:15)
at Parser.handlePacket (/workspace/node_modules/pg-protocol/dist/parser.js:126:29)
at Parser.parse (/workspace/node_modules/pg-protocol/dist/parser.js:39:38)
at Socket.stream.on (/workspace/node_modules/pg-protocol/dist/index.js:10:42)
at Socket.emit (events.js:198:13)
at Socket.EventEmitter.emit (domain.js:448:20)
at addChunk (_stream_readable.js:288:12)
at readableAddChunk (_stream_readable.js:269:11)
at Socket.Readable.push (_stream_readable.js:224:10)
at Pipe.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
I created the table using the following commands in the GCP Cloud Shell (then populated with a data from a CSV):
\connect ingredients;
CREATE TABLE tableName (name VARCHAR(255), otherField VARCHAR(255), ... );
In that console, if I run the query SELECT * FROM tableName;, I see the correct data listed.
Why does Knex not see the table: tableName, but the GCP Cloud Shell does?
BTW, I am definitely connecting to the correct db, as I see the same error logs in the Cloud SQL logging interface.
Looks like you are creating the table tableName without quoting, which makes it actually lower case (case insensitive). So when creating schema do:
CREATE TABLE "tableName" ("name" VARCHAR(255), "otherField" VARCHAR(255), ... );
or use only lower-case table / column names.

sequelize.findOrCreate did not save even though the table is empty

My app is saving a socket related information into a socketlist table. The idea is if the entry with the socket_id does not exist, then create an entry in postgres table. otherwise to do nothing. Here is the code:
await SocketList.findOrCreate({ where: {socket_id : socket_id, active: true}, default: {event_id: event_id, user_id: user_id, server_id: server_id}});
sequelizejs 4.42.0 is used. The socketlist table is empty but the above code throws the error below:
Executing (325bc621-414d-4e3f-9f2b-230f66537631): START TRANSACTION;
Executing (325bc621-414d-4e3f-9f2b-230f66537631): SELECT "id", "user_id", "socket_id", "event_id", "server_id", "active" FROM "socketlists" AS "socketlist" WHERE "socketlist"."socket_id" = '2TPk6DpsxPwttaemAAAA' AND "socketlist"."active" = true LIMIT 1;
Executing (325bc621-414d-4e3f-9f2b-230f66537631): CREATE OR REPLACE FUNCTION pg_temp.testfunc(OUT response "socketlists", OUT sequelize_caught_exception text) RETURNS RECORD AS $func_4fe094a05f394fe8a0ec032506b86e21$ BEGIN INSERT INTO "socketlists" ("id","socket_id","active") VALUES (NULL,'2TPk6DpsxPwttaemAAAA',true) RETURNING * INTO response; EXCEPTION WHEN unique_violation THEN GET STACKED DIAGNOSTICS sequelize_caught_exception = PG_EXCEPTION_DETAIL; END $func_4fe094a05f394fe8a0ec032506b86e21$ LANGUAGE plpgsql; SELECT (testfunc.response).*, testfunc.sequelize_caught_exception FROM pg_temp.testfunc(); DROP FUNCTION IF EXISTS pg_temp.testfunc();
Executing (325bc621-414d-4e3f-9f2b-230f66537631): COMMIT;
Socket was not saved for userId: 1 { SequelizeDatabaseError: null value in column "id" violates not-null constraint
at Query.formatError (C:\d\code\js\emps_bbone\node_modules\sequelize\lib\dialects\postgres\query.js:363:16)
at query.catch.err (C:\d\code\js\emps_bbone\node_modules\sequelize\lib\dialects\postgres\query.js:86:18)
at tryCatcher (C:\d\code\js\emps_bbone\node_modules\bluebird\js\release\util.js:16:23)
at Promise._settlePromiseFromHandler (C:\d\code\js\emps_bbone\node_modules\bluebird\js\release\promise.js:512:31)
at Promise._settlePromise (C:\d\code\js\emps_bbone\node_modules\bluebird\js\release\promise.js:569:18)
at Promise._settlePromise0 (C:\d\code\js\emps_bbone\node_modules\bluebird\js\release\promise.js:614:10)
at Promise._settlePromises (C:\d\code\js\emps_bbone\node_modules\bluebird\js\release\promise.js:690:18)
at _drainQueueStep (C:\d\code\js\emps_bbone\node_modules\bluebird\js\release\async.js:138:12)
at _drainQueue (C:\d\code\js\emps_bbone\node_modules\bluebird\js\release\async.js:131:9)
at Async._drainQueues (C:\d\code\js\emps_bbone\node_modules\bluebird\js\release\async.js:147:5)
at Immediate.Async.drainQueues [as _onImmediate] (C:\d\code\js\emps_bbone\node_modules\bluebird\js\release\async.js:17:14)
at runCallback (timers.js:705:18)
at tryOnImmediate (timers.js:676:5)
at processImmediate (timers.js:658:5)
name: 'SequelizeDatabaseError',
parent:
{ error: null value in column "id" violates not-null constraint
at Connection.parseE (C:\d\code\js\emps_bbone\node_modules\pg\lib\connection.js:601:11)
at Connection.parseMessage (C:\d\code\js\emps_bbone\node_modules\pg\lib\connection.js:398:19)
at Socket.<anonymous> (C:\d\code\js\emps_bbone\node_modules\pg\lib\connection.js:120:22)
at Socket.emit (events.js:182:13)
at addChunk (_stream_readable.js:283:12)
at readableAddChunk (_stream_readable.js:264:11)
at Socket.Readable.push (_stream_readable.js:219:10)
at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
name: 'error',
length: 465,
severity: 'ERROR',
code: '23502',
detail:
'Failing row contains (null, null, 2TPk6DpsxPwttaemAAAA, null, null, t).',
hint: undefined,
position: undefined,
internalPosition: undefined,
internalQuery: undefined,
where:
'SQL statement "INSERT INTO "socketlists" ("id","socket_id","active") VALUES (NULL,\'2TPk6DpsxPwttaemAAAA\',true) RETURNING *"\nPL/pgSQL function pg_temp_3.testfunc() line 1 at SQL statement',
schema: 'public',
table: 'socketlists',
column: 'id',
dataType: undefined,
constraint: undefined,
file:
'd:\\pginstaller.auto\\postgres.windows-x64\\src\\backend\\executor\\execmain.c',
line: '2041',
routine: 'ExecConstraints',
sql:
'CREATE OR REPLACE FUNCTION pg_temp.testfunc(OUT response "socketlists", OUT sequelize_caught_exception text) RETURNS RECORD AS $func_4fe094a05f394fe8a0ec032506b86e21$ BEGIN INSERT INTO "socketlists" ("id","socket_id","active") VALUES (NULL,\'2TPk6DpsxPwttaemAAAA\',true) RETURNING * INTO response; EXCEPTION WHEN unique_violation THEN GET STACKED DIAGNOSTICS sequelize_caught_exception = PG_EXCEPTION_DETAIL; END $func_4fe094a05f394fe8a0ec032506b86e21$ LANGUAGE plpgsql; SELECT (testfunc.response).*, testfunc.sequelize_caught_exception FROM pg_temp.testfunc(); DROP FUNCTION IF EXISTS pg_temp.testfunc();' },
original:
{ error: null value in column "id" violates not-null constraint
at Connection.parseE (C:\d\code\js\emps_bbone\node_modules\pg\lib\connection.js:601:11)
at Connection.parseMessage (C:\d\code\js\emps_bbone\node_modules\pg\lib\connection.js:398:19)
at Socket.<anonymous> (C:\d\code\js\emps_bbone\node_modules\pg\lib\connection.js:120:22)
at Socket.emit (events.js:182:13)
at addChunk (_stream_readable.js:283:12)
at readableAddChunk (_stream_readable.js:264:11)
at Socket.Readable.push (_stream_readable.js:219:10)
at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
name: 'error',
length: 465,
severity: 'ERROR',
code: '23502',
detail:
'Failing row contains (null, null, 2TPk6DpsxPwttaemAAAA, null, null, t).',
hint: undefined,
position: undefined,
internalPosition: undefined,
internalQuery: undefined,
where:
'SQL statement "INSERT INTO "socketlists" ("id","socket_id","active") VALUES (NULL,\'2TPk6DpsxPwttaemAAAA\',true) RETURNING *"\nPL/pgSQL function pg_temp_3.testfunc() line 1 at SQL statement',
schema: 'public',
table: 'socketlists',
column: 'id',
dataType: undefined,
constraint: undefined,
file:
'd:\\pginstaller.auto\\postgres.windows-x64\\src\\backend\\executor\\execmain.c',
line: '2041',
routine: 'ExecConstraints',
sql:
'CREATE OR REPLACE FUNCTION pg_temp.testfunc(OUT response "socketlists", OUT sequelize_caught_exception text) RETURNS RECORD AS $func_4fe094a05f394fe8a0ec032506b86e21$ BEGIN INSERT INTO "socketlists" ("id","socket_id","active") VALUES (NULL,\'2TPk6DpsxPwttaemAAAA\',true) RETURNING * INTO response; EXCEPTION WHEN unique_violation THEN GET STACKED DIAGNOSTICS sequelize_caught_exception = PG_EXCEPTION_DETAIL; END $func_4fe094a05f394fe8a0ec032506b86e21$ LANGUAGE plpgsql; SELECT (testfunc.response).*, testfunc.sequelize_caught_exception FROM pg_temp.testfunc(); DROP FUNCTION IF EXISTS pg_temp.testfunc();' },
sql:
'CREATE OR REPLACE FUNCTION pg_temp.testfunc(OUT response "socketlists", OUT sequelize_caught_exception text) RETURNS RECORD AS $func_4fe094a05f394fe8a0ec032506b86e21$ BEGIN INSERT INTO "socketlists" ("id","socket_id","active") VALUES (NULL,\'2TPk6DpsxPwttaemAAAA\',true) RETURNING * INTO response; EXCEPTION WHEN unique_violation THEN GET STACKED DIAGNOSTICS sequelize_caught_exception = PG_EXCEPTION_DETAIL; END $func_4fe094a05f394fe8a0ec032506b86e21$ LANGUAGE plpgsql; SELECT (testfunc.response).*, testfunc.sequelize_caught_exception FROM pg_temp.testfunc(); DROP FUNCTION IF EXISTS pg_temp.testfunc();' }
Here is the model definition:
const SocketList = db.define('socketlist', {
id: {type: Sql.INTEGER,
primaryKey:true,
min: 1
},
user_id: { type: Sql.INTEGER
},
socket_id: {type: Sql.STRING,
unique: true,
min: 1
},
event_id: {type: Sql.INTEGER,
min: 1
},
server_id: {type: Sql.STRING
},
active: {type: Sql.BOOLEAN,
defaultValue: true,
},
}....
you have to create data include id
what about try this?
id: {
type: Sql.INTEGER,
primaryKey:true,
autoIncrement: true
}

Duplicate key value violates unique constraint with Postgres, Knex, and Promises

I'm having a very weird issue. When I insert five roles into my "repository" table with unique ids, the following error below comes up multiple times (same id being mentioned!). I'm not using autoincrement for 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' }
Postgres code generated by knex:
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 schema for repository:
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');
})
Code run to insert Repository:
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)}
);
Sounds like your database already had a row inserted with primary key id == 80073079.
To be sure about it try to query DB rows with that key just before inserting. I just wonder how are those ids generated, since you are clearly not using id sequence for it.
It is possible that input data, where IDs were fetched is corrupted and has duplicate ids