Tai-Iro

pg-mem and sequelize association error

Sep 22nd, 2025 (edited)
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 3.69 KB | Source Code | 0 0
  1. import { Sequelize, DataTypes } from 'sequelize'; // 6.37.7, latest at time of post
  2. import { newDb } from 'pg-mem'; // 3.0.5, latest at time of post
  3.  
  4. const db = newDb();
  5.  
  6. const sequelize = new Sequelize({
  7.   dialect: 'postgres',
  8.   dialectModule: db.adapters.createPg({ autoCreateForeignKeyIndices: true }),
  9.   logging: true,
  10. });
  11.  
  12. // Define the tables/Sequelize models
  13. const author = sequelize.define('author', {
  14.   // Model attributes are defined here
  15.   authorId: { autoIncrement: true, type: DataTypes.INTEGER, allowNull: false, primaryKey: true, field: 'author_id' },
  16.   name: { type: DataTypes.STRING, allowNull: false, field: 'name' },
  17. }, {
  18.   // Other model options go here
  19.   tableName: 'author', schema: 'public', timestamps: false,
  20. });
  21.  
  22. const textbook = sequelize.define('textbook', {
  23.   bookId: { autoIncrement: true, type: DataTypes.INTEGER, allowNull: false, primaryKey: true, field: 'book_id' },
  24.   title: { type: DataTypes.STRING, allowNull: false, field: 'title' },
  25. }, {
  26.   tableName: 'textbook', schema: 'public', timestamps: false,
  27. });
  28.  
  29. // join/through-table definition
  30. const textbookAuthor = sequelize.define('textbookAuthor', {
  31.   bookId: { type: DataTypes.INTEGER, allowNull: false, primaryKey: true, field: 'book_id' },
  32.   authorId: { type: DataTypes.INTEGER, allowNull: false, primaryKey: true, field: 'author_id' },
  33. }, {
  34.   tableName: 'textbook_author', schema: 'public', timestamps: false,
  35. });
  36.  
  37. // Standard many-to-many association
  38. author.belongsToMany(textbook, { through: textbookAuthor, foreignKey: 'authorId', otherKey: 'bookId' });
  39. textbook.belongsToMany(author, { through: textbookAuthor, otherKey: 'authorId', foreignKey: 'bookId' });
  40.  
  41. // Alternate many-to-many association, using 2 one-to-many associations instead
  42. author.hasMany(textbookAuthor, { foreignKey: 'authorId' });
  43. textbookAuthor.belongsTo(author, { foreignKey: 'authorId' });
  44. textbook.hasMany(textbookAuthor, { foreignKey: 'bookId' });
  45. textbookAuthor.belongsTo(textbook, { foreignKey: 'bookId' });
  46.  
  47. await sequelize.sync();
  48.  
  49. // Insert the test data
  50. db.public.none('INSERT INTO "public"."author"("name") VALUES (\'John Doe\'), (\'Einstien\'), (\'Steve\'), (\'Bill\'), (\'Bob\');');
  51. db.public.none('INSERT INTO "public"."textbook"("title") VALUES (\'World History\'), (\'Literature 101\'), (\'Math 101\'), (\'Science 101\');');
  52. db.public.none('INSERT INTO "public"."textbook_author"("author_id", "book_id") VALUES (1,1),(2,1);');
  53. console.log(db.public.many('SELECT * FROM public."textbook_author"'));
  54.  
  55. // This one works with pg-mem, & requires the "2 one-to-many" pattern
  56. // Sequelize doc: https://sequelize.org/docs/v6/advanced-association-concepts/advanced-many-to-many/#using-one-to-many-relationships-instead
  57. const resTest = await textbook.findOne({
  58.   where: { bookId: 1 },
  59.   include: {
  60.     model: textbookAuthor,
  61.     // right: true, // works as expected
  62.     // required: true, // works as expected
  63.     include: {
  64.         model: author,
  65.         // right: true, // works as expected
  66.         // required: true, // usually works. ONLY errors if the "textbookAuthor" is "required: false"
  67.     },
  68.   },
  69. });
  70. console.dir(resTest.dataValues, { depth: 3 });
  71.  
  72. try {
  73.   // this one just needs the "belongsToMany" pattern
  74.   // does NOT work with pg-mem, but works in actual databases
  75.   // Squelize doc: https://sequelize.org/docs/v6/core-concepts/assocs/#implementation-2
  76.   const resTest = await textbook
  77.   .findOne({
  78.     where: { bookId: 1 },
  79.     include: {
  80.       model: author,
  81.       // These options alter the SQL questy, but seem to have no affect on if it works
  82.       // right: true,
  83.       // required: true,
  84.     },
  85.   });
  86.   console.dir(resTest.dataValues, { depth: 3 });
  87. } catch (e) {
  88.   console.log(e);
  89. }
  90. process.exit();
Advertisement
Add Comment
Please, Sign In to add comment