I have a model with such init:
Group.init({
id: {
type: DataTypes.UUID,
primaryKey: true,
allowNull: false,
defaultValue: DataTypes.UUIDV4,
},
name: Sequelize.STRING,
});
I also have an associated migration file:
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('Groups', {
id: {
type: Sequelize.UUID,
primaryKey: true,
allowNull: false,
defaultValue: Sequelize.UUIDV4,
},
name: Sequelize.STRING,
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('Groups');
},
};
I'm trying to bulkInsert inside the seeders while creating groups and I'm passing only a name property, expecting the DB to create uuids:
const groups = [{ name: 'group-1' }, { name: 'group-2' }];
return queryInterface.bulkInsert('Groups', groups, {
returning: true,
validate: true,
individualHooks: true,
});
},
Yet there is an error during this seed:
ERROR: null value in column "id" violates not-null constraint
How can I automatically generate uuids?
I faced a similar issue. In my case (on the migration file), I changed
defaultValue: Sequelize.UUIDV4,
to
defaultValue: Sequelize.literal('uuid_generate_v4()'),
PS: I was working on Postgres, so uuid modules needed to be enabled on the schema
Related
I am trying to configure a Foreign Key association between two tables on 'non-PrimaryKey' fields for one-to-many relation:
Asset.belongsTo(AssetClass)
AssetClass.hasMany(Asset)
I create tables first and add the constraint in the third migration:
migrations\20220621223626-create-asset.js
'use strict';
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.createTable('Assets', {
ticker: {
allowNull: false,
autoIncrement: false,
primaryKey: true,
type: Sequelize.STRING
},
shortName: {
allowNull: false,
type: Sequelize.STRING
},
fullName: {
allowNull: false,
type: Sequelize.STRING
},
assetClass: {
allowNull: false,
type: Sequelize.STRING
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
async down(queryInterface, Sequelize) {
await queryInterface.dropTable('Assets');
}
};
migrations\20220622035610-create-asset-class.js
'use strict';
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.createTable('AssetClasses', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
name: {
type: Sequelize.STRING,
allowNull: false
},
prio: {
type: Sequelize.INTEGER,
allowNull: false
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
async down(queryInterface, Sequelize) {
await queryInterface.dropTable('AssetClasses');
}
};
migrations\20220627211055-add-constraint-fk_asset-assetClass.js
'use strict';
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.addConstraint('Assets', {
fields: ['assetClass'], //existing field in Assets table
type: 'foreign key',
name: 'fk_asset-assetClass',
references: {
table: 'AssetClasses', //reference to AssetClasses table
field: 'name' //name of the target field
}
});
},
async down(queryInterface, Sequelize) {
await queryInterface.removeConstraint('Assets', 'fk_asset-assetClass');
}
};
After running db::migrate I am getting a following error message:
SQLITE_ERROR: foreign key mismatch - "Assets_backup" referencing "AssetClasses"
which leaves me with a Assets_backup table in the database which I need to remove manually.
What seems to works though is:
Creating a new column assetClassId in Assets table and referencing it to Primary Key field (id) of AssetClasses table:
//addConstraint migration
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.addConstraint('Assets', {
fields: ['assetClassId'], //existing field in Assets table
type: 'foreign key',
name: 'fk_asset-assetClass',
references: {
table: 'AssetClasses', //reference to AssetClasses table
field: 'id' //name of the target field
}
});
},
async down(queryInterface, Sequelize) {
await queryInterface.removeConstraint('Assets', 'fk_asset-assetClass');
}
};
//createTable Assets migration
assetClassId: {
allowNull: false,
type: Sequelize.INTEGER
},
How can I make it work for existing non-PK fields?
I have this code I used for db migration using Sequelize
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('tasks', {
id: {
type: Sequelize.BIGINT,
autoIncrement: true,
primaryKey: true,
allowNull: false
},
uuid: {
type: Sequelize.STRING,
allowNull: false
},
task: {
type: Sequelize.STRING,
allowNull: false
},
description: {
type: Sequelize.STRING,
allowNull: false
},
status: {
type: Sequelize.STRING,
allowNull: false
},
createdAt: {
type: Sequelize.DATE,
defaultValue: Sequelize.NOW,
allowNull: false
},
completedAt: {
type: Sequelize.DATE
}
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('tasks');
}
};
After running npx sequelize-cli db:migrate it successfully created a table in PhpMyAdmin. The problem is, I specified in my migration file the column names createdAt and completedAt but in my PhpMyAdmin, the column names have a different format namely: created_at and completed_at.
I did created_at and completed_at on my previous migration so what I did was to undo it, so it deleted the table in my DB. So I created another migration using the code above but I still have the same column names, created_at and completed_at when I should be getting createdAt and completedAt instead.
Deleted my completed_at column and used created_At , updatedAt , deletedAt
I'm new to nodejs. I have created a template with expressJs. For migration and ORM purposes I am using squelizeJs with mysql2 plugin. I have created migrations and models for my tables. But I could not change the default behavior when creating foreign keys, which is to change the values of onUpdate and onDelete
How can I implement this SQL query inside sequelize migration?
CONSTRAINT `fk_keywords_2`
FOREIGN KEY (`bot_id`)
REFERENCES `mydb`.`bots` (`id`)
ON DELETE RESTRICT
ON UPDATE NO ACTION)
I have tried
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('Keywords', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER.UNSIGNED
},
bot_id: {
allowNull: false,
type: Sequelize.INTEGER.UNSIGNED,
references: {
model: 'Bots',
key: 'id'
},
onUpdate: 'NO ACTION',
onDelete: 'RESTRICT'
},
parent_id: {
type: Sequelize.INTEGER.UNSIGNED
},
keyword: {
allowNull: false,
type: Sequelize.STRING
},
time_duration: {
type: Sequelize.STRING
},
is_all_message_config: {
allowNull: false,
type: Sequelize.BOOLEAN,
defaultValue: 0
},
is_catch_all_config: {
allowNull: false,
type: Sequelize.BOOLEAN,
defaultValue: 0
},
blockedAt: {
type: Sequelize.DATE
},
deletedAt: {
type: Sequelize.DATE
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
}, {
uniqueKeys: {
keyword_unique_for_bot_and_parent: {
customIndex: true,
fields: ['bot_id', 'parent_id', 'keyword', 'deletedAt']
}
}
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('Keywords');
}
};
It creates a foreign key but, both onUpdate and onDelete are set to RESTRICT
I went through their documentation but could not find something that works.
You should try to add that action in your Keywords model file where we can define association.
static associate(models) {
// define association here
Keywords.hasMany(models.Bots, {
foreignKey: 'id',
onUpdate: 'RESTRICT',
onDelete: 'RESTRICT'
});
};
Thanks
I'm using sequelize 4.32 and I was trying to write a self-association in one of the tables, I'm not sure if there is something else that I need to do to solve this relation, my goal is to get all the records in my table and include all the records associated with each one
this is the error that I'm getting in the console:
You have used the alias adjucent_stands in two separate associations. Aliased associations must have unique aliases
below you'll find my model:
module.exports = (sequelize, DataTypes) => {
const stands = sequelize.define('stands', {
id: {
type: DataTypes.INTEGER,
unique: true,
allowNull: false,
primaryKey: true,
autoIncrement: true,
},
name: {
type: DataTypes.STRING,
field: 'name',
unique: {
args: true,
msg: 'Name already exists ',
},
},
location: {
type: DataTypes.JSON,
field: 'location',
},
remote: {
type: DataTypes.BOOLEAN,
field: 'remote',
defaultValue: false,
},
created_at: {
type: DataTypes.DATE(3),
defaultValue: sequelize.literal('CURRENT_TIMESTAMP(3)'),
},
updated_at: {
type: DataTypes.DATE(3),
defaultValue: sequelize.literal('CURRENT_TIMESTAMP(3)'),
},
}, { freezeTableName: true, timestamps: true, underscored: true });
stands.associate = (models) => {
stands.hasMany(stands, { as: 'adjucent_stands' });
};
return stands;
};
I'm currently running through using Node-Express and Sequelize as the ORM for PostgreSQL. I am trying to test my API route when I noticed that my todoId is not being returned. When I check my table I see a null value even though I have allowNull:false set.
module.exports = {
up: (queryInterface, Sequelize) =>
queryInterface.createTable('TodoItems', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER,
},
content: {
type: Sequelize.STRING,
allowNull: false,
},
complete: {
type: Sequelize.BOOLEAN,
defaultValue: false,
},
createdAt: {
allowNull: false,
type: Sequelize.DATE,
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE,
},
todoId: {
type: Sequelize.INTEGER,
onDelete: 'CASCADE',
allowNull: false,
references: {
model: 'Todos',
key: 'id',
as: 'todoId',
},
},
}),
down:(queryInterface/*, Sequelize*/) => queryInterface.dropTable('TodoItems'),
};
I have tried everything from dropping my database and creating a new one and migrations for the schema all over again. What I'm trying to achieve is to ensure that the value of the todoId column references and maps my the id of a separate table called todo.
Solved it. The error was using a deprecated class methods