Sequelize es un ORM para Nodejs que te permite agilizar bastante tus desarrollos que incluyan bases de datos relacionales como Postgres, MySQL, MariaDB, SQLite y SQL Server.
De MySQL Community Downloads, descargue e instale:
Crea un nuevo proyecto, según Express - Bases y Express - ORM (Básico).
hito2-api
Tome como referencia las instrucciones el tutorial Express - ORM (Básico) o Apuntes, para:
sequelize model:create --name fotoetiqueta --attributes foto_id:integer,etiqueta_id:integer
models/fotoetiqueta
, agregue la clave tableName y el nombre de la tabla fotoetiquetas
a la cual estará relacionado
...
modelName: 'fotoetiqueta',
tableName: 'fotoetiquetas'
...
migrations/YYYYMMDDHHMMSS-create-fotoetiqueta
para que el nombre de la tabla sea etiquetas
...
await queryInterface.createTable('fotoetiquetas'
...
await queryInterface.dropTable('fotoetiquetas'
...
sequelize migration:generate --name associate-foto-etiqueta
migrations/YYYYMMDDHHMMSS-associate-foto-etiqueta
, agregue en la función de ejecución de cambios up
...
await queryInterface.addConstraint('fotoetiquetas', {
fields: ['foto_id'],
name: 'foto_id_fk',
type: 'foreign key',
references: {
table: 'fotos',
field: 'id'
},
onDelete: 'cascade',
onUpdate: 'set null'
});
await queryInterface.addConstraint('fotoetiquetas', {
fields: ['etiqueta_id'],
name: 'etiqueta_id_fk',
type: 'foreign key',
references: {
table: 'etiquetas',
field: 'id'
},
onDelete: 'cascade',
onUpdate: 'set null'
});
...
migrations/YYYYMMDDHHMMSS-associate-foto-etiqueta
, agregue en la función de reversión de cambios down
await queryInterface.removeConstraint('fotoetiquetas', 'foto_id_fk')
await queryInterface.removeConstraint('fotoetiquetas', 'etiqueta_id_fk')
fotoetiqueta
sequelize seed:create --name fotoetiqueta
...
let [fotos, fotos_metadata] = await queryInterface.sequelize.query('SELECT id FROM fotos')
let [etiquetas, etiquetas_metadata] = await queryInterface.sequelize.query('SELECT id FROM etiquetas')
await queryInterface.bulkInsert('fotoetiquetas', [
{ foto_id: fotos[0].id, etiqueta_id: etiquetas[0].id, createdAt: new Date(), updatedAt: new Date() },
{ foto_id: fotos[0].id, etiqueta_id: etiquetas[1].id, createdAt: new Date(), updatedAt: new Date() },
{ foto_id: fotos[1].id, etiqueta_id: etiquetas[1].id, createdAt: new Date(), updatedAt: new Date() }
], {});
...
...
await queryInterface.bulkDelete('fotoetiquetas', null, {});
...
Asociación: Entre los modelos foto -< fotoetiqueta >- etiqueta
models/foto.js
, modifique el método associate con la asociacion lógica al modelo etiqueta
...
static associate(models) {
// define association here
models.foto.belongsToMany(models.etiqueta, { through: 'fotoetiqueta', foreignKey: "foto_id" } );
}
...
models/etiqueta.js
, modifique el método associate con la asociacion lógica al modelo foto
...
static associate(models) {
// define association here
models.etiqueta.belongsToMany(models.foto, { through: 'fotoetiqueta', foreignKey: "etiqueta_id" });
}
...
Manejador de rutas y controladores:
etiqueta
...
const Foto = require('../models').foto;
const Etiqueta = require('../models').etiqueta;
...
/findAll/json
al:
etiqueta
texto
...
const Foto = require('../models').foto;
const Etiqueta = require('../models').etiqueta;
...
Foto.findAll({
attributes: { exclude: ["updatedAt"] },
include: [{
model: Etiqueta,
attributes: ['texto'],
through: {attributes: []}
}],
})
http://localhost:3000/fotos/findAll/json