Skip to content

References option produces different database constraint names with sync/createTable and changeColumn (Postgres) #8147

@wolframkleis

Description

@wolframkleis

What you are doing?

I create a foreign key using the "references" options of the attribute.
Depending on how I do this, I get different constraint names in Postgres database

  • sync(), queryInterface.createTable(), and queryInterface.addColumn() create a database constraint name like ${tableName}_${fieldName}_fkey
  • queryInterface.changeColumn() creates a database constraint name like ${fieldName}_foreign_idx

This makes life harder for me, because I planned to generate migrations for column changes by just passing the current attribute options to queryInterface.changeColumn(). With the different resulting constraint names this is not a good idea. When I have to delete a constraint in a later migration, I would have to check first in the database how it is actually named.

What do you expect to happen?

I expect that identical attribute options create the same database result, no matter whether I use sync, createTable, or changeColumn

It would be great (and much more consistent) if the automatically given constraint name would be the same name in all 4 cases.

Alternatively it would help if a could specify the name of the foreign key in 'changeColumn()'

What is actually happening?

sync

The follwoing 2 code snippets create a foreign key constraint named test1_col1_fkey

sequelize.define('test1',{	
	id:  { type: Sequelize.INTEGER, primaryKey: true},
	col1: { type: Sequelize.INTEGER, references:{ model:"test2", key:"id"}},
	col2:  { type: Sequelize.INTEGER}
},{freezeTableName: true});

this creates constraint test1_col1_fkey

createTable()

Now I use queryInterface,createTable() (for migration)

sequelize.queryInterface.createTable("test1",{	
	id:  { type: Sequelize.INTEGER, primaryKey: true},
	col1: { type: Sequelize.INTEGER,references:{ model:"test2", key:"id"}},
	col2:  { type: Sequelize.INTEGER}
})

This creates the same constraint test1_col1_fkey, too
Same with addColumn(), I have not included the example here. Produces same result.

changeColumn()

sequelize.queryInterface.changeColumn("test1","col1"
 ,{type:Sequelize.INTEGER,references:{model:"test2",key:"id"}})})

this creates database constraint name "col1_foreign_idx"

SQL

with sync() and with createtable(), the constraint name name is generated by Postgres, because the SQL does not sepecify it

CREATE TABLE IF NOT EXISTS 
  "test1" ("id" INTEGER , 
  "col1" INTEGER REFERENCES "test2" ("id"), 
  "col2" INTEGER, PRIMARY KEY ("id"));

when I use changeColumn(), sequelize chooses a constraint name different from the default name:

ALTER TABLE "test1" 
     ADD CONSTRAINT "col1_foreign_idx" FOREIGN KEY ("col1") REFERENCES "test2" ("id");

Dialect: postgres
Database version: 9.6
Sequelize version: 4.4.10

Metadata

Metadata

Assignees

No one assigned

    Labels

    breaking changeFor issues and PRs. Changes that break compatibility and require a major version increment.type: bugDEPRECATED: replace with the "bug" issue type

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions