Sequelize Update with Object - node.js

I have a code using sequelize to update one record and then return this updated record:
const companyId = req.params.id
const companyNewDetail = req.body
console.log("companyNewDetail", companyNewDetail)
await Company.update(companyNewDetail, {
where: {
companyId,
},
})
const company = await Company.findOne({
where: {
companyId,
},
})
res.status(200).send({ status: 0, data: company })
It is working but I have to seperate into two query statements. Is there a way I can mix them together? I want to pass the update parameter with a object rather than destructuring the object and assign to the instance one by one.

The returning option of Model.update still only supports PostgreSQL for sequelize v6.
For example:
import { sequelize } from '../../db';
import { Model, DataTypes, Sequelize } from 'sequelize';
// const sequelize = new Sequelize('sqlite::memory:');
class Company extends Model {}
Company.init(
{
companyId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
},
name: DataTypes.STRING,
},
{ sequelize, tableName: 'companies' },
);
(async function test() {
try {
await sequelize.sync({ force: true });
// seed
await Company.create({ name: 'google' });
// test
const companyId = 1;
const companyNewDetail = { name: 'reddit' };
const result = await Company.update(companyNewDetail, {
where: {
companyId,
},
returning: true,
});
console.log(result);
} catch (error) {
console.log(error);
} finally {
await sequelize.close();
}
})();
If you use postgres dialect, you will get the following result:
Executing (default): DROP TABLE IF EXISTS "companies" CASCADE;
Executing (default): DROP TABLE IF EXISTS "companies" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "companies" ("companyId" SERIAL , "name" VARCHAR(255), PRIMARY KEY ("companyId"));
Executing (default): SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'companies' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): INSERT INTO "companies" ("companyId","name") VALUES (DEFAULT,$1) RETURNING *;
Executing (default): UPDATE "companies" SET "name"=$1 WHERE "companyId" = $2 RETURNING *
[
1,
[
Company {
dataValues: [Object],
_previousDataValues: [Object],
_changed: {},
_modelOptions: [Object],
_options: [Object],
isNewRecord: false
}
]
]
The first element of the result array is the number of affected rows for the updating operation. The second element is the sequelize model instances of updated rows.
For sqlite3, you will get:
Executing (default): DROP TABLE IF EXISTS `companies`;
Executing (default): DROP TABLE IF EXISTS `companies`;
Executing (default): CREATE TABLE IF NOT EXISTS `companies` (`companyId` INTEGER PRIMARY KEY AUTOINCREMENT, `name` VARCHAR(255), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL);
Executing (default): PRAGMA INDEX_LIST(`companies`)
Executing (default): INSERT INTO `companies` (`companyId`,`name`,`createdAt`,`updatedAt`) VALUES (NULL,$1,$2,$3);
Executing (default): UPDATE `companies` SET `name`=$1,`updatedAt`=$2 WHERE `companyId` = $3
[ undefined, 1 ]
So, you need to do an additional query for other databases after updating the rows in the table.

Related

Sequelize migration changing column to be FK and then undo failing

I'm trying to create migration file to changeColumn to be string (from enum) and to reference other table.
const enumStatus = ['PENDING', 'SUCCESSFUL', 'FAILED', 'FAILED_LAST_VALUE_MISSING', 'FAILED_LAST_DATE_MISSING', 'FAILED_OLD_LAST_DATE'];
module.exports = {
up: async(queryInterface, Sequelize) => {
return Promise.all([
queryInterface.changeColumn('MeasurementTestResults', 'status', {
type: Sequelize.STRING,
allowNull: false
}), queryInterface.addConstraint('MeasurementTestResults', {
fields: ['status'],
type: 'foreign key',
name: 'statusFk',
references: {
table: 'MeasurementTestResultStatusEnums',
field: 'code'
},
onDelete: 'cascade',
onUpdate: 'cascade'
})
]);
},
down: async(queryInterface, Sequelize) => {
return Promise.all([
queryInterface.removeConstraint('MeasurementTestResults', 'statusFk'),
queryInterface.changeColumn('MeasurementTestResults', 'status', {
type: Sequelize.ENUM(...enumStatus),
allowNull: false
})
]);
}
};
db:migrate run flawlesly, but when i try to call db:migrate:undo it will execute commands out of order?
== 20201217194748-measurementTestResult_changeColumn_status: reverting =======
Executing (default): SELECT CONSTRAINT_CATALOG AS constraintCatalog, CONSTRAINT_NAME AS constraintName, CONSTRAINT_SCHEMA AS constraintSchema, CONSTRAINT_TYPE AS constraintType, TABLE_NAME AS tableName, TABLE_SCHEMA AS tableSchema from INFORMATION_SCHEMA.TABLE_CONSTRA
INTS WHERE table_name='MeasurementTestResults' AND constraint_name = 'statusFk' AND TABLE_SCHEMA = 'iot_crcm_application_data1';
Executing (default): ALTER TABLE `MeasurementTestResults` CHANGE `status` `status` ENUM('PENDING', 'SUCCESSFUL', 'FAILED', 'FAILED_LAST_VALUE_MISSING', 'FAILED_LAST_DATE_MISSING', 'FAILED_OLD_LAST_DATE') NOT NULL;
Executing (default): ALTER TABLE `MeasurementTestResults`
DROP FOREIGN KEY `statusFk`;
ERROR: (conn=143438, no: 1832, SQLState: HY000) Cannot change column 'status': used in a foreign key constraint 'statusFk'
sql: ALTER TABLE `MeasurementTestResults` CHANGE `status` `status` ENUM('PENDING', 'SUCCESSFUL', 'FAILED', 'FAILED_LAST_VALUE_MISSING', 'FAILED_LAST_DATE_MISSING', 'FAILED_OLD_LAST_DATE') NOT NULL; - parameters:[]
then when i try to remove queryInterface.removeConstraint('MeasurementTestResults', 'statusFk'), this line from down script, it works, but no before i try it with error...
Don't try to execute structure changes that depends on each other in parallel using Promise.all. You better call them one by one:
await queryInterface.removeConstraint('MeasurementTestResults', 'statusFk')
await queryInterface.changeColumn('MeasurementTestResults', 'status', {
type: Sequelize.ENUM(...enumStatus),
allowNull: false
})
The same goes for up method too.

sequelize model exclude subfield within a jsonb field

I have a postgresql table structured with a jsonb field named external_data:
external_data: {a: 1, b:2, c:3}
I know that in sequelize model definitions, you can exclude a field by including in the options properties a defaultScope like this:
{defaultScope: {attributes: { exclude: ['external_data'] }}
When I do that to exclude the entire field, it works, i.e. external_data doesn't show up in returned results. However, I'd like to exclude a specific subfield. I've tried exclude: ['external_data.b'] but that doesn't seem to work.
Does sequelize allow excluding subfields within jsonb fields? And if so, what's the proper format of the exclude attribute to do it?
From the docs: https://sequelize.org/v5/manual/scopes.html
Scopes are defined in the model definition and can be finder objects, or functions returning finder objects - except for the default scope, which can only be an object
So, you can define the scope via a function that returns the finder objects so that you can implement the complex scope.
E.g.
import { sequelize } from '../../db';
import { Model, DataTypes, Op } from 'sequelize';
class TableA extends Model {}
TableA.init(
{
external_data: DataTypes.JSONB,
},
{
sequelize,
modelName: 'table_a',
defaultScope: {
attributes: { exclude: ['external_data'] },
},
scopes: {
exclude(subField) {
return {
where: {
external_data: {
[subField]: {
[Op.eq]: null,
},
},
},
};
},
},
},
);
(async function test() {
try {
// create tables
await sequelize.sync({ force: true });
// seed
await TableA.bulkCreate([
{ external_data: { a: 1, b: 2, c: 3 } },
{ external_data: { a: 10, c: 30 } },
{ external_data: { a: 100 } },
]);
// test
// test case 1: exclude subfield "b"
const result1 = await TableA.scope({ method: ['exclude', 'b'] }).findAll({ raw: true });
console.log('result1:', result1);
// test case 2: exclude subfield "c"
const result2 = await TableA.scope({ method: ['exclude', 'c'] }).findAll({ raw: true });
console.log('result2:', result2);
} catch (error) {
console.log(error);
} finally {
await sequelize.close();
}
})();
The execution results:
Executing (default): DROP TABLE IF EXISTS "table_a" CASCADE;
Executing (default): DROP TABLE IF EXISTS "table_a" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "table_a" ("id" SERIAL , "external_data" JSONB, PRIMARY KEY ("id"));
Executing (default): SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'table_a' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): INSERT INTO "table_a" ("id","external_data") VALUES (DEFAULT,'{"a":1,"b":2,"c":3}'),(DEFAULT,'{"a":10,"c":30}'),(DEFAULT,'{"a":100}') RETURNING *;
Executing (default): SELECT "id", "external_data" FROM "table_a" AS "table_a" WHERE ("table_a"."external_data"#>>'{b}') IS NULL;
result1: [ { id: 2, external_data: { a: 10, c: 30 } },
{ id: 3, external_data: { a: 100 } } ]
Executing (default): SELECT "id", "external_data" FROM "table_a" AS "table_a" WHERE ("table_a"."external_data"#>>'{c}') IS NULL;
result2: [ { id: 3, external_data: { a: 100 } } ]
check the database:
node-sequelize-examples=# select * from "table_a";
id | external_data
----+--------------------------
1 | {"a": 1, "b": 2, "c": 3}
2 | {"a": 10, "c": 30}
3 | {"a": 100}
(3 rows)
Dependencies versions: "sequelize": "^5.21.3", postgres:9.6
source code: https://github.com/mrdulin/node-sequelize-examples/tree/master/src/examples/stackoverflow/61053931

sequelize methods from association fooInstance.getBars() returning a wrong value

I've got 2 models with a many-to-many association through another model. By default, Sequelize creates instance methods for both models as you all may know (https://sequelize.org/master/manual/assocs.html#special-methods-mixins-added-to-instances).
My problem is that the fooInstance.getBars() method and fooInstance.countBars() both return the wrong number of records.
The database was setup using sequelize migration files.
The 3 models are below.
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define(
"User",
{
firstName: DataTypes.STRING
},
{}
);
User.associate = function(models) {
// associations can be defined here
User.belongsToMany(models.Week, {
through: models.Roster,
foreignKey: {
name: "weekId"
}
});
};
return User;
};
"use strict";
module.exports = (sequelize, DataTypes) => {
const Week = sequelize.define(
"Week",
{
date: {
type: DataTypes.DATE,
allowNull: false,
unique: true
}
},
{}
);
Week.associate = function(models) {
// associations can be defined here
Week.belongsToMany(models.User, {
through: models.Roster,
foreignKey: {
name: "userId",
allowNull: true
}
});
};
return Week;
};
"use strict";
module.exports = (sequelize, DataTypes) => {
const Roster = sequelize.define(
"Roster",
{
weekId: {
type: DataTypes.INTEGER,
allowNull: false,
unique: false
},
userId: {
type: DataTypes.INTEGER,
allowNull: true,
unique: false
}
},
{}
);
Roster.associate = function(models) {
// associations can be defined here
};
return Roster;
};
Before I test out the methods, I created 1 record in weeks and 5 records in users then I created 5 associations using 5 Roster.create() in rosters.
When I do a query in my routes file like this await Week.getUsers(), instead of returning 5 users in an array, it returned 1 in an array. Similarly, the await Week.countUsers() code returned 1 instead of 5.
Please help!
Please let me know if I miss any important information.
Thank you!
Like the docs says:
When an association is defined between two models, the instances of those models gain special methods to interact with their associated counterparts.
You are trying to call these special methods on Model class. Here is a working example:
import { sequelize } from '../../db';
import { Model, DataTypes, BelongsToManyGetAssociationsMixin, BelongsToManyCountAssociationsMixin } from 'sequelize';
class User extends Model {}
User.init(
{
firstName: DataTypes.STRING,
},
{ sequelize, modelName: 'User' },
);
class Week extends Model {
public getUsers!: BelongsToManyGetAssociationsMixin<User>;
public countUsers!: BelongsToManyCountAssociationsMixin;
}
Week.init(
{
date: {
type: DataTypes.DATE,
allowNull: false,
unique: true,
},
},
{ sequelize, modelName: 'Week' },
);
class Roster extends Model {}
Roster.init(
{
weekId: {
type: DataTypes.INTEGER,
allowNull: false,
unique: false,
},
userId: {
type: DataTypes.INTEGER,
allowNull: true,
unique: false,
},
},
{ sequelize, modelName: 'Roster' },
);
User.belongsToMany(Week, { through: Roster, foreignKey: { name: 'weekId' } });
Week.belongsToMany(User, { through: Roster, foreignKey: { name: 'userId', allowNull: true } });
(async function test() {
try {
// create tables
await sequelize.sync({ force: true });
// seed
const week = await Week.create(
{
date: new Date(),
Users: [
{ firstName: 'james' },
{ firstName: 'elsa' },
{ firstName: 'tim' },
{ firstName: 'lee' },
{ firstName: 'jasmine' },
],
},
{ include: [User] },
);
// test
const count = await week.countUsers();
console.log('count:', count);
const users = await week.getUsers();
console.log('users count:', users.length);
} catch (error) {
console.log(error);
} finally {
await sequelize.close();
}
})();
The execution results:
Executing (default): DROP TABLE IF EXISTS "Roster" CASCADE;
Executing (default): DROP TABLE IF EXISTS "Week" CASCADE;
Executing (default): DROP TABLE IF EXISTS "User" CASCADE;
Executing (default): DROP TABLE IF EXISTS "User" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "User" ("id" SERIAL , "firstName" VARCHAR(255), PRIMARY KEY ("id"));
Executing (default): SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'User' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): DROP TABLE IF EXISTS "Week" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "Week" ("id" SERIAL , "date" TIMESTAMP WITH TIME ZONE NOT NULL UNIQUE, PRIMARY KEY ("id"));
Executing (default): SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'Week' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): DROP TABLE IF EXISTS "Roster" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "Roster" ("weekId" INTEGER NOT NULL REFERENCES "User" ("id") ON DELETE CASCADE ON UPDATE CASCADE, "userId" INTEGER REFERENCES "Week" ("id") ON DELETE CASCADE ON UPDATE CASCADE, UNIQUE ("weekId", "userId"), PRIMARY KEY ("weekId","userId"));
Executing (default): SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'Roster' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): INSERT INTO "Week" ("id","date") VALUES (DEFAULT,$1) RETURNING *;
Executing (default): INSERT INTO "User" ("id","firstName") VALUES (DEFAULT,$1) RETURNING *;
Executing (default): INSERT INTO "User" ("id","firstName") VALUES (DEFAULT,$1) RETURNING *;
Executing (default): INSERT INTO "User" ("id","firstName") VALUES (DEFAULT,$1) RETURNING *;
Executing (default): INSERT INTO "User" ("id","firstName") VALUES (DEFAULT,$1) RETURNING *;
Executing (default): INSERT INTO "User" ("id","firstName") VALUES (DEFAULT,$1) RETURNING *;
Executing (default): INSERT INTO "Roster" ("weekId","userId") VALUES ($1,$2) RETURNING *;
Executing (default): INSERT INTO "Roster" ("weekId","userId") VALUES ($1,$2) RETURNING *;
Executing (default): INSERT INTO "Roster" ("weekId","userId") VALUES ($1,$2) RETURNING *;
Executing (default): INSERT INTO "Roster" ("weekId","userId") VALUES ($1,$2) RETURNING *;
Executing (default): INSERT INTO "Roster" ("weekId","userId") VALUES ($1,$2) RETURNING *;
Executing (default): SELECT COUNT("User"."id") AS "count" FROM "User" AS "User" INNER JOIN "Roster" AS "Roster" ON "User"."id" = "Roster"."weekId" AND "Roster"."userId" = 1;
count: 5
Executing (default): SELECT "User"."id", "User"."firstName", "Roster"."weekId" AS "Roster.weekId", "Roster"."userId" AS "Roster.userId" FROM "User" AS "User" INNER JOIN "Roster" AS "Roster" ON "User"."id" = "Roster"."weekId" AND "Roster"."userId" = 1;
users count: 5
check the database:
node-sequelize-examples=# select * from "User";
id | firstName
----+-----------
1 | james
2 | elsa
3 | tim
4 | lee
5 | jasmine
(5 rows)
node-sequelize-examples=# select * from "Week";
id | date
----+---------------------------
1 | 2020-04-14 01:56:56.55+00
(1 row)
node-sequelize-examples=# select * from "Roster";
weekId | userId
--------+--------
1 | 1
2 | 1
3 | 1
4 | 1
5 | 1
(5 rows)
Dependencies versions: "sequelize": "^5.21.3", postgres:9.6
source code: https://github.com/mrdulin/node-sequelize-examples/tree/master/src/examples/stackoverflow/60805725

Sequelize findAll() try to get unregistered field

i have problem with sequelize, i try to use findAll() to get data from my table, but there is an error which says unknown column jobs.userId in field list which i never register in my model or in my table
i have tried to use findAndCountAll() but still have same error, i also tried to remove all associatoin at get same result, the only work solution so far is put userId on exclude array
here's my controller
const jobData = await jobs.findAll({
attributes:{exclude:['updatedAt']},
include:[{
model:jobOwners,
as:'owner',
attributes:['id','profilePicture'],
include:[{
model:users,
as:'user',
attributes:['id','name'],
},{
model:districts,
as:'district',
attributes:['id','name']
}]
}]
});
here's my jobs model
'use strict';
module.exports = (sequelize, DataTypes) => {
const jobs = sequelize.define('jobs', {
jobOwnerId:{
type:DataTypes.INTEGER,
allowNull:false
},
caption: {
type:DataTypes.STRING,
allowNull:false
},
description: {
type:DataTypes.TEXT,
allowNull:false
},
districtId: {
type:DataTypes.INTEGER,
allowNull:false
},
address: {
type:DataTypes.TEXT,
allowNull:false
},
poster: {
type:DataTypes.TEXT,
allowNull:true
},
contactPerson: {
type:DataTypes.STRING,
allowNull:false
}
}, {});
jobs.associate = function(models) {
jobs.belongsTo(models.jobOwners,{as:'owner',foreignKey:'jobOwnerId'})
jobs.belongsTo(models.districts,{as:'districts', foreignKey:'districtId'})
};
return jobs;
};
here's my table
CREATE TABLE jobs (
id int(11) NOT NULL,
jobOwnerId int(11) NOT NULL,
caption varchar(255) NOT NULL,
description text,
districtId int(11) NOT NULL,
address text NOT NULL,
poster text,
contactPerson varchar(15) NOT NULL,
createdAt datetime NOT NULL,
updatedAt datetime NOT NULL
)
here's is the query result shown on console
SELECT jobs.id, jobs.jobOwnerId, jobs.caption, jobs.description, jobs.districtId, jobs.address,
jobs.poster, jobs.contactPerson, jobs.createdAt, jobs.userId, owner.id AS owner.id, owner.profilePicture AS owner.profilePicture,
owner->user.id AS owner.user.id, owner->user.name AS owner.user.name, owner->district.id
AS owner.district.id, owner->district.name AS owner.district.name FROM jobs AS jobs
LEFT OUTER JOIN jobOwners AS owner ON jobs.jobOwnerId = owner.id LEFT OUTER JOIN users AS owner->user
ON owner.userId = owner->user.id LEFT OUTER JOIN districts AS owner->district ON owner.districtId = owner->district.id;
there should be no jobs.userId
Problem solved, the problem not from jobs model or jobs controller, but it comes from users model, i create association hasMany jobs and it couses the problem..

Associations not working for Sequelize

I run the below mutation first, creates the fish, I also created a river all ready. Why are rivers and fishes empty?
Graphql:
query {
fishes {
name
species
rivers {
name
}
}
river(id: 1) {
name
fishes {
name}
}
}
# mutation {
# createFish (name: "Orange-Vall Smallmouth Yellowfish", species: "Labeobarbus aeneus", riverId: 1) {
# name
# rivers {
# name
# }
# }
# }
The results are below:
{
"data": {
"fishes": [
{
"name": "Orange-Vall Smallmouth Yellowfish",
"species": "Labeobarbus aeneus",
"rivers": []
}
],
"river": {
"name": "Orange River",
"fishes": []
}
}
}
Below are the two models:
const Fish = sequelize.define('fish', schema);
Fish.associate = models => {
Fish.belongsToMany(models.River, { through: 'RiverFish' });
};
const River = sequelize.define('river', schema);
River.associate = models => {
River.belongsToMany(models.Fish, { through: 'RiverFish', as: 'Fishes' });
};
Part of the graphql query:
River: {
fishes: river => river.getFishes(), },
Fish: {
rivers: fish => fish.getRivers(), },
Sequelize logs:
Executing (default): CREATE TABLE IF NOT EXISTS `fishes` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` VARCHAR(255), `species` VARCHAR(255) DEFAULT NULL, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL);
Connection has been established successfully.
Executing (default): PRAGMA INDEX_LIST(`fishes`)
Executing (default): CREATE TABLE IF NOT EXISTS `rivers` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` VARCHAR(255), `alternative` VARCHAR(255) DEFAULT NULL, `geojson` JSON, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL);
Executing (default): PRAGMA INDEX_LIST(`rivers`)
Executing (default): CREATE TABLE IF NOT EXISTS `RiverFish` (`createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, `fishId` INTEGER NOT NULL REFERENCES `fishes` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, `riverId` INTEGER NOT NULL REFERENCES `rivers` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, PRIMARY KEY (`fishId`, `riverId`));
Executing (default): PRAGMA INDEX_LIST(`RiverFish`)
Executing (default): PRAGMA INDEX_INFO(`sqlite_autoindex_RiverFish_1`)
EDIT
If I change my models the results are working from the River side of things:
River.hasMany(models.Fish, { as: 'Fishes' });
Fish.belongsToMany(models.River, { through: 'RiverFish', as: 'Rivers' });
{
"data": {
"fishes": [
{
"id": "1",
"name": "Orange-Vall Smallmouth Yellowfish",
"species": "Labeobarbus aeneus",
"rivers": []
}
],
"river": {
"name": "Orange River",
"fishes": [
{
"name": "Orange-Vall Smallmouth Yellowfish"
}
]
},
"rivers": null
}
UPDATE
I believe this could be the issue. I have this in a my models directory:
import Fish from './Fish';
import River from "./River";
const models = {
Fish,
River
};
Object.keys(models).forEach(name => {
const model = models[name];
if (typeof model.associate === 'function') {
model.associate(models);
}
});
export {
Fish, River,
};

Resources