Reputation: 1586
I'm writing an express API, with sequelize and postgresl, postgresl is being hosted at Heroku.
When I try to create a relationship between those tables below, it gives me this error
Unhandled rejection SequelizeDatabaseError: relation "questions" does not exist
The idea is that a question has an id, a title, a score, has many answers, and one Right Answer.
Question Model:
import { sequelize } from "../Util/db"
import { Users } from "./User"
import { Answer } from "./Answer"
const Sequelize = require("sequelize")
const Question = sequelize.define("question", {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
title: {
type: Sequelize.STRING
},
score: {
type: Sequelize.INTEGER,
defaultValue: 0
},
content: {
type: Sequelize.JSONB
}
})
Question.belongsTo(Users)
Question.hasMany(Answer, { as: "Answers", foreignKey: "id"})
Question.hasOne(Answer, {as: "RightAnswer", foreignKey: "id"})
Question.sync({force: false}).then(() => {
// Table created
console.log("Question Table Synchronized")
})
interface QuestionType {
id: number
title: string
score: number
content: string
}
export { Question, QuestionType }
Answer Model:
import { sequelize } from "../Util/db"
import { Users } from "./User"
import { Question } from "./Question"
const Sequelize = require("sequelize")
const Answer = sequelize.define("answer", {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
score: {
type: Sequelize.INTEGER,
defaultValue: 0
},
content: {
type: Sequelize.JSONB
}
})
Answer.belongsTo(Users)
Answer.sync({force: false}).then(() => {
// Table created
console.log("Answer Table Synchronized")
})
interface AnswerType {
id: number
score: number
content: string
}
export { Answer, AnswerType }
Creation script, created by sequelize
Executing (default): CREATE TABLE IF NOT EXISTS "users" ("id" SERIAL , "email" VARCHAR(255), "score" INTEGER DEFAULT 0, "name" VARCHAR(255), "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, PRIMARY KEY ("id"));
Executing (default): CREATE TABLE IF NOT EXISTS "answers" ("id" SERIAL REFERENCES "questions" ("id") ON DELETE CASCADE ON UPDATE CASCADE, "score" INTEGER DEFAULT 0, "content" JSONB, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" INTEGER REFERENCES "users" ("id") ON DELETE SET NULL ON UPDATE CASCADE, PRIMARY KEY ("id"));
Executing (default): CREATE TABLE IF NOT EXISTS "questions" ("id" SERIAL , "title" VARCHAR(255), "score" INTEGER DEFAULT 0, "content" JSONB, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" INTEGER REFERENCES "users" ("id") ON DELETE SET NULL ON UPDATE CASCADE, PRIMARY KEY ("id"));
Executing (default): SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'users' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Unhandled rejection SequelizeDatabaseError: relation "questions" does not exist
at Query.formatError (/home/mazzardo/Codigo/pas/node-typescript-boilerplate/node_modules/sequelize/lib/dialects/postgres/query.js:363:16)
at query.catch.err (/home/mazzardo/Codigo/pas/node-typescript-boilerplate/node_modules/sequelize/lib/dialects/postgres/query.js:86:18)
at tryCatcher (/home/mazzardo/Codigo/pas/node-typescript-boilerplate/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/home/mazzardo/Codigo/pas/node-typescript-boilerplate/node_modules/bluebird/js/release/promise.js:512:31)
at Promise._settlePromise (/home/mazzardo/Codigo/pas/node-typescript-boilerplate/node_modules/bluebird/js/release/promise.js:569:18)
at Promise._settlePromise0 (/home/mazzardo/Codigo/pas/node-typescript-boilerplate/node_modules/bluebird/js/release/promise.js:614:10)
at Promise._settlePromises (/home/mazzardo/Codigo/pas/node-typescript-boilerplate/node_modules/bluebird/js/release/promise.js:689:18)
at Async._drainQueue (/home/mazzardo/Codigo/pas/node-typescript-boilerplate/node_modules/bluebird/js/release/async.js:133:16)
at Async._drainQueues (/home/mazzardo/Codigo/pas/node-typescript-boilerplate/node_modules/bluebird/js/release/async.js:143:10)
at Immediate.Async.drainQueues (/home/mazzardo/Codigo/pas/node-typescript-boilerplate/node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:651:20)
at tryOnImmediate (timers.js:624:5)
at processImmediate [as _immediateCallback] (timers.js:596:5)
Executing (default): SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'questions' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
User Table Synchronized
Question Table Synchronized
Side note, I'm using typescript on the project
Upvotes: 1
Views: 1271
Reputation: 7282
This could be because of a race condition with each sync
. Each call to sync
in asynchronous and since we have foreign key constraints, it is possible that one of the table is not created which is looking for association. I think you should use
sequelize.sync()
which should solve your issue.
From the docs
Because Sequelize is doing a lot of magic, you have to call Sequelize.sync after setting the associations! Doing so will allow you the following:
Upvotes: 2