Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { Sequelize, DataTypes } from 'sequelize'; // 6.37.7, latest at time of post
- import { newDb } from 'pg-mem'; // 3.0.5, latest at time of post
- const db = newDb();
- const sequelize = new Sequelize({
- dialect: 'postgres',
- dialectModule: db.adapters.createPg({ autoCreateForeignKeyIndices: true }),
- logging: true,
- });
- // Define the tables/Sequelize models
- const author = sequelize.define('author', {
- // Model attributes are defined here
- authorId: { autoIncrement: true, type: DataTypes.INTEGER, allowNull: false, primaryKey: true, field: 'author_id' },
- name: { type: DataTypes.STRING, allowNull: false, field: 'name' },
- }, {
- // Other model options go here
- tableName: 'author', schema: 'public', timestamps: false,
- });
- const textbook = sequelize.define('textbook', {
- bookId: { autoIncrement: true, type: DataTypes.INTEGER, allowNull: false, primaryKey: true, field: 'book_id' },
- title: { type: DataTypes.STRING, allowNull: false, field: 'title' },
- }, {
- tableName: 'textbook', schema: 'public', timestamps: false,
- });
- // join/through-table definition
- const textbookAuthor = sequelize.define('textbookAuthor', {
- bookId: { type: DataTypes.INTEGER, allowNull: false, primaryKey: true, field: 'book_id' },
- authorId: { type: DataTypes.INTEGER, allowNull: false, primaryKey: true, field: 'author_id' },
- }, {
- tableName: 'textbook_author', schema: 'public', timestamps: false,
- });
- // Standard many-to-many association
- author.belongsToMany(textbook, { through: textbookAuthor, foreignKey: 'authorId', otherKey: 'bookId' });
- textbook.belongsToMany(author, { through: textbookAuthor, otherKey: 'authorId', foreignKey: 'bookId' });
- // Alternate many-to-many association, using 2 one-to-many associations instead
- author.hasMany(textbookAuthor, { foreignKey: 'authorId' });
- textbookAuthor.belongsTo(author, { foreignKey: 'authorId' });
- textbook.hasMany(textbookAuthor, { foreignKey: 'bookId' });
- textbookAuthor.belongsTo(textbook, { foreignKey: 'bookId' });
- await sequelize.sync();
- // Insert the test data
- db.public.none('INSERT INTO "public"."author"("name") VALUES (\'John Doe\'), (\'Einstien\'), (\'Steve\'), (\'Bill\'), (\'Bob\');');
- db.public.none('INSERT INTO "public"."textbook"("title") VALUES (\'World History\'), (\'Literature 101\'), (\'Math 101\'), (\'Science 101\');');
- db.public.none('INSERT INTO "public"."textbook_author"("author_id", "book_id") VALUES (1,1),(2,1);');
- console.log(db.public.many('SELECT * FROM public."textbook_author"'));
- // This one works with pg-mem, & requires the "2 one-to-many" pattern
- // Sequelize doc: https://sequelize.org/docs/v6/advanced-association-concepts/advanced-many-to-many/#using-one-to-many-relationships-instead
- const resTest = await textbook.findOne({
- where: { bookId: 1 },
- include: {
- model: textbookAuthor,
- // right: true, // works as expected
- // required: true, // works as expected
- include: {
- model: author,
- // right: true, // works as expected
- // required: true, // usually works. ONLY errors if the "textbookAuthor" is "required: false"
- },
- },
- });
- console.dir(resTest.dataValues, { depth: 3 });
- try {
- // this one just needs the "belongsToMany" pattern
- // does NOT work with pg-mem, but works in actual databases
- // Squelize doc: https://sequelize.org/docs/v6/core-concepts/assocs/#implementation-2
- const resTest = await textbook
- .findOne({
- where: { bookId: 1 },
- include: {
- model: author,
- // These options alter the SQL questy, but seem to have no affect on if it works
- // right: true,
- // required: true,
- },
- });
- console.dir(resTest.dataValues, { depth: 3 });
- } catch (e) {
- console.log(e);
- }
- process.exit();
Advertisement
Add Comment
Please, Sign In to add comment