Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sequelize can't synchronize models which references other tables #11048

Open
1 of 5 tasks
TitaneBoy opened this issue Jun 7, 2019 · 7 comments
Open
1 of 5 tasks

Sequelize can't synchronize models which references other tables #11048

TitaneBoy opened this issue Jun 7, 2019 · 7 comments
Labels
dialect: postgres For issues and PRs. Things that involve PostgreSQL (and do not involve all dialects). type: bug

Comments

@TitaneBoy
Copy link

What are you doing?

Trying to synchronize my defined Models with my sequelize instance

Code sample

import { Model, Options, Sequelize } from 'sequelize';
import groupPrivilege from '../../../models/group_privilege';
import groupUser from '../../../models/group_user';
import measurement from '../../../models/measurement';
import measurementV2 from '../../../models/measurement_v2';
import privilege from '../../../models/privilege';
import readings_resume from '../../../models/readings_resume';
import session from '../../../models/sessions';
import user from '../../../models/user';

protected importDatabaseModels() {
    const groupPrivilegeModel = groupPrivilege(this._sequelizer);
    const groupUserModel = groupUser(this._sequelizer);
    const privilegeModel = privilege(this._sequelizer);
    const userModel = user(this._sequelizer);
    const measurementModel = measurement(this._sequelizer);
    const readingsResumeModel = readings_resume(this._sequelizer);

    session(this._sequelizer);
    measurementV2(this._sequelizer);

    userModel.belongsTo(groupUserModel, {foreignKey: 'group_id', targetKey: 'id'});
    userModel.belongsTo(groupPrivilegeModel, {foreignKey: 'group_id', targetKey: 'group_id'});
    groupPrivilegeModel.belongsTo(userModel, {foreignKey: 'group_id', targetKey: 'group_id'});
    groupPrivilegeModel.belongsTo(privilegeModel, {foreignKey: 'privilege_id', targetKey: 'id'});
    groupPrivilegeModel.belongsTo(groupUserModel, {foreignKey: 'group_id', targetKey: 'id'});
    privilegeModel.hasMany(groupPrivilegeModel, {foreignKey: 'privilege_id'});
    groupUserModel.hasMany(groupPrivilegeModel, {foreignKey: 'group_id'});

    readingsResumeModel.belongsTo(measurementModel, {foreignKey: 'measurement_id', targetKey: 'id'});
    measurementModel.hasMany(readingsResumeModel, {foreignKey: 'measurement_id'});

    this._sequelizer.sync({alter: true})
      .then(() => {
        debugConsole('Database tables correctly synchronized');
      })
      .catch((error) => {
        debugConsole(`Error when synchronizing database tables: ${error}`);
      });
  }

User Model

import { BuildOptions, DataTypes, InitOptions, Model, ModelAttributes, Sequelize } from 'sequelize';

export interface IUserModel extends Model {
  readonly id: number;
  group_id: number;
  username: string;
  password: Date;
  readonly createdAt: Date;
  readonly updateAt: Date;
}

export type UserModel = typeof Model & (new (values ?: object, options ?: BuildOptions) => IUserModel);

export default function user(sequelizeInstance: Sequelize) {
  const options: InitOptions = {
    freezeTableName: true,
    name: {singular: 'user', plural: 'users'},
    sequelize: sequelizeInstance,
    tableName: 'user',
    timestamps: true,
    underscored: true,
  };

  const attributes: ModelAttributes = {
    group_id: {
      allowNull: true,
      defaultValue: '1',
      references: {
        key: 'id',
        model: 'group_user',
      },
      type: DataTypes.INTEGER,
    },
    id: {
      autoIncrement: true,
      primaryKey: true,
      type: DataTypes.INTEGER,
    },
    password: {
      allowNull: false,
      type: DataTypes.TEXT,
    },
    username: {
      allowNull: false,
      type: DataTypes.TEXT,
      unique: true,
    },
  };

  return sequelizeInstance.define('user', attributes, options) as UserModel;
}

To Reproduce
Steps to reproduce the behavior:

  1. Define models X, Y, ...
  2. Run the following
  3. See error

What do you expect to happen?

I expect sequelize to synchronize my defined models with my databasde

What is actually happening?

An error occurs while sequelize is trying to execute its generated sql instructions...

Here is the query Sequelize is trying to execute:

ALTER TABLE "user" ALTER COLUMN "group_id" SET DEFAULT '1' REFERENCES "group_user" ("id") ON DELETE SET NULL ON UPDATE CASCADE;ALTER TABLE "user" ALTER COLUMN "group_id" TYPE INTEGER;

image

I tried to execute manually with pgAdmin the generated sql query and this is what I got:

image

In english, the translated error will be something like: "Syntax error near << REFERENCES >>

Environment

Dialect:

  • mysql
  • postgres
  • sqlite
  • mssql
  • any
    Dialect library version:
    "pg": "7.11.0",
    "pg-hstore": "2.3.3",
    Database version: "PostgreSQL 9.4.4, compiled by Visual C++ build 1800, 64-bit"
    Sequelize version: 5.8.7
    Node Version: v10.10.0
    OS: Windows 7 Professional SP1, 64 bits
    If TypeScript related: TypeScript version: 3.5.1
@papb papb self-assigned this Jul 21, 2019
@papb
Copy link
Member

papb commented Jul 25, 2019

Does this only happen with postgres? Can you please check another dialect?

@papb papb removed their assignment Jul 25, 2019
@papb papb added dialect: postgres For issues and PRs. Things that involve PostgreSQL (and do not involve all dialects). status: awaiting response For issues and PRs. OP must respond (or change something, if it is a PR). Maintainers have no action type: bug labels Jul 25, 2019
@TitaneBoy
Copy link
Author

Hello... I unfortunetly don't have the necessary resources to test it with other dialects... It can take me a while to have these resources... but for sure, it doesn't work with postgres dialect

@papb
Copy link
Member

papb commented Aug 1, 2019

You can instantiate an in-memory SQLite instance as follows:

  1. npm install sqlite3
  2. new Sequelize('sqlite::memory:')

Can you please try it?

@kartonrad
Copy link

yes, this is not an issue in sqlite 3

@github-actions github-actions bot removed the status: awaiting response For issues and PRs. OP must respond (or change something, if it is a PR). Maintainers have no action label May 10, 2021
@kartonrad
Copy link

wait, i'm not sure sure that model.sync({alter:true}) in sqlite actually executes ALTER TABLE statements

regardless, sqlite allows the REFERENCES clause in ALTER TABLE ALTER COLUMN, postgres sql does not, instead requiring something like ALTER TABLE ADD CONSTRAINT

i'm facing the same issue currently

@kartonrad
Copy link

https://www.sqlite.org/lang_altertable.html
https://www.postgresql.org/docs/current/sql-altertable.html

yea, sqllite doesn't support ALTER COLUMN, only DROP and ADD column

@github-actions
Copy link
Contributor

github-actions bot commented Nov 9, 2021

This issue has been automatically marked as stale because it has been open for 14 days without activity. It will be closed if no further activity occurs within the next 14 days. If this is still an issue, just leave a comment or remove the "stale" label. 🙂

@github-actions github-actions bot added the stale label Nov 9, 2021
@WikiRik WikiRik removed the stale label Nov 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dialect: postgres For issues and PRs. Things that involve PostgreSQL (and do not involve all dialects). type: bug
Projects
None yet
Development

No branches or pull requests

4 participants