L'arrière-plan
Je construis un projet avec SequelizeJS , un ORM populaire pour NodeJS. Lors de la conception d'un schéma, il semble y avoir deux tactiques:
Ma compréhension est que le n ° 1 est meilleur pour le prototypage rapide, mais que le n ° 2 est une meilleure pratique pour les projets qui devraient évoluer dans le temps et où les données de production doivent pouvoir survivre aux migrations.
Cette question concerne la tactique n ° 2.
La (les) question (s)
Mes tables ont des relations qui doivent être reflétées par des clés étrangères.
Comment créer des tables avec des relations de clés étrangères entre elles via l'interface de requête Sequelize?
Quelles colonnes et tables auxiliaires sont requises par Sequelize? Par exemple, il apparaît que des colonnes spécifiques telles que createdAt ou updatedAt sont attendues.
Comment créer des tables avec des relations de clés étrangères entre elles via l'interface de requête Sequelize?
La méthode .createTable()
prend un dictionnaire de colonnes. Vous pouvez voir la liste des attributs valides dans la documentation pour .define()
, en particulier en regardant le [attributes.column.*]
lignes dans la table params.
Pour créer un attribut avec une relation de clé étrangère, utilisez les champs "références" et "referencesKey":
Par exemple, ce qui suit créerait une table users
et une table user_emails
table qui référence la table des utilisateurs.
queryInterface.createTable('users', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
}
}).then(function() {
queryInterface.createTable('user_emails', {
userId: {
type: Sequelize.INTEGER,
references: { model: 'users', key: 'id' }
}
})
});
Quelles colonnes et tables auxiliaires sont nécessaires pour sequelize? Par exemple, il apparaît que des colonnes spécifiques telles que createdAt ou updatedAt sont attendues.
Il semble qu'un modèle standard attendra une colonne id
, updatedAt
et createdAt
pour chaque table.
queryInterface.createTable('users', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
createdAt: {
type: Sequelize.DATE
},
updatedAt: {
type: Sequelize.DATE
}
}
Si vous définissez paranoid
sur true
sur votre modèle, vous avez également besoin d'un horodatage deletedAt
.
Je veux offrir une autre alternative plus manuelle parce que lors de l'utilisation des migrations manuelles et de queryInterface, j'ai rencontré le problème suivant: j'avais 2 fichiers dans le dossier de migration comme ceci
migrations/create-project.js
migrations/create-projectType.js
parce que project
avait la colonne projectTypeId
elle faisait référence à projectType
, qui n'était pas encore créée en raison de l'ordre des fichiers et cela provoquait une erreur.
Je l'ai résolu en ajoutant une contrainte de clé étrangère après avoir créé les deux tables. Dans mon cas, j'ai décidé de l'écrire à l'intérieur create-projectType.js
:
queryInterface.createTable('project_type', {
// table attributes ...
})
.then(() => queryInterface.addConstraint('project', ['projectTypeId'], {
type: 'FOREIGN KEY',
name: 'FK_projectType_project', // useful if using queryInterface.removeConstraint
references: {
table: 'project_type',
field: 'id',
},
onDelete: 'no action',
onUpdate: 'no action',
}))