我正在关注 Sequelize 关于如何创建多对多关系的文档,但是,我不断收到此错误:
'as' must be defined for many-to-many self-associations
即使我正在关注此文档 - https://sequelize.org/master/manual/advanced-many-to-many.html我有 2 个模型,用户和服务器,我尝试定义这样的关系:
let User = require('./models/User');
let Server = require('./models/User');
User.belongsToMany(Server, { through: 'Server_User' });
Server.belongsToMany(User, { through: 'Server_User' });
但我收到以下错误:'as' must be defined for many-to-many self-associations
用户:let Sequelize = require('sequelize');
let sequelize = require('../controllers/DatabaseController');
let User = sequelize.define('user', {
id: {
primaryKey: true,
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
},
username: {
type: Sequelize.STRING,
allowNull: false,
},
password: {
type: Sequelize.STRING,
allowNull: false,
},
email: {
type: Sequelize.STRING,
allowNull: false,
}
})
module.exports = User;
服务器:let Sequelize = require('sequelize');
let sequelize = require('../controllers/DatabaseController');
let Server = sequelize.define('server', {
id: {
primaryKey: true,
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
},
user_id: {
type: Sequelize.INTEGER,
allowNull: false,
},
name: {
type: Sequelize.STRING,
allowNull: false
},
thumbnail: {
type: Sequelize.STRING(1400),
allowNull: false,
},
endpoint: {
type: Sequelize.UUID,
defaultValue: Sequelize.UUIDV4,
allowNull: false,
},
rooms: {
type: Sequelize.JSON,
allowNull: false,
defaultValue: [{ name: 'General', history: []}]
}
})
module.exports = Server;
最佳答案
它适用于 "sequelize": "^5.21.3"
。该错误可能是由其他代码引起的。这是一个完整的工作示例:./models/User.ts
:
import { sequelize } from '../../../db';
import Sequelize from 'sequelize';
let User = sequelize.define('user', {
id: {
primaryKey: true,
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
},
username: {
type: Sequelize.STRING,
allowNull: false,
},
password: {
type: Sequelize.STRING,
allowNull: false,
},
email: {
type: Sequelize.STRING,
allowNull: false,
},
});
export default User;
./models/Server.ts
:import { sequelize } from '../../../db';
import Sequelize from 'sequelize';
let Server = sequelize.define('server', {
id: {
primaryKey: true,
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
},
user_id: {
type: Sequelize.INTEGER,
allowNull: false,
},
name: {
type: Sequelize.STRING,
allowNull: false,
},
thumbnail: {
type: Sequelize.STRING(1400),
allowNull: false,
},
endpoint: {
type: Sequelize.UUID,
defaultValue: Sequelize.UUIDV4,
allowNull: false,
},
rooms: {
type: Sequelize.JSON,
allowNull: false,
defaultValue: [{ name: 'General', history: [] }],
},
});
export default Server;
./models/index.ts
:import User from './User';
import Server from './Server';
(User as any).belongsToMany(Server, { through: 'Server_User' });
(Server as any).belongsToMany(User, { through: 'Server_User' });
export { User, Server };
index.ts
:import { User, Server } from './models';
import { sequelize } from '../../db';
import faker from 'faker';
(async function test() {
try {
await sequelize.sync({ force: true });
await (User as any).bulkCreate(
[
{
id: 1,
username: faker.name.findName(),
password: faker.internet.password(),
email: faker.internet.email(),
servers: [
{ user_id: 1, name: faker.name.findName(), thumbnail: faker.random.image(), endpoint: faker.random.uuid() },
{ user_id: 1, name: faker.name.findName(), thumbnail: faker.random.image(), endpoint: faker.random.uuid() },
],
},
{
id: 2,
username: faker.name.findName(),
password: faker.internet.password(),
email: faker.internet.email(),
servers: [
{ user_id: 2, name: faker.name.findName(), thumbnail: faker.random.image(), endpoint: faker.random.uuid() },
],
},
],
{ include: [Server] },
);
} catch (error) {
console.log(error);
} finally {
await sequelize.close();
}
})();
测试函数的执行结果:Executing (default): DROP TABLE IF EXISTS "Server_User" CASCADE;
Executing (default): DROP TABLE IF EXISTS "server" 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 , "username" VARCHAR(255) NOT NULL, "password" VARCHAR(255) NOT NULL, "email" VARCHAR(255) NOT NULL, 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 "server" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "server" ("id" SERIAL , "user_id" INTEGER NOT NULL, "name" VARCHAR(255) NOT NULL, "thumbnail" VARCHAR(1400) NOT NULL, "endpoint" UUID NOT NULL, "rooms" JSON NOT NULL DEFAULT '[{"name":"General","history":[]}]', 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 = 'server' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): DROP TABLE IF EXISTS "Server_User" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "Server_User" ("userId" INTEGER REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE CASCADE, "serverId" INTEGER REFERENCES "server" ("id") ON DELETE CASCADE ON UPDATE CASCADE, PRIMARY KEY ("userId","serverId"));
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 = 'Server_User' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): INSERT INTO "user" ("id","username","password","email") VALUES (1,'Kayley O''Reilly Jr.','jbXGDr5PHon4XH4','Elissa_MacGyver@gmail.com'),(2,'Daisha Kohler PhD','mAQ1ttIF1LcQ8mq','Albin_Weimann30@yahoo.com') RETURNING *;
Executing (default): INSERT INTO "server" ("id","user_id","name","thumbnail","endpoint","rooms") VALUES (DEFAULT,1,'Ms. Denis Kilback','http://lorempixel.com/640/480/food','e7bff975-abcd-4b86-8af2-024557bdd5d4','[{"name":"General","history":[]}]'),(DEFAULT,1,'Everardo Anderson','http://lorempixel.com/640/480/technics','79ad1819-cb64-4846-8aea-ff4a5fdce1fb','[{"name":"General","history":[]}]'),(DEFAULT,2,'Jannie Torp','http://lorempixel.com/640/480/technics','7ed6449b-5abd-4734-8733-076e1e535b82','[{"name":"General","history":[]}]') RETURNING *;
Executing (default): INSERT INTO "Server_User" ("userId","serverId") VALUES (1,1),(1,2),(2,3) RETURNING *;
数据库中的数据记录:node-sequelize-examples=# select * from "server";
id | user_id | name | thumbnail | endpoint | rooms
----+---------+-------------------+----------------------------------------+--------------------------------------+-----------------------------------
1 | 1 | Major Schamberger | http://lorempixel.com/640/480/abstract | ec9b17d2-6722-469f-a208-c76bc44d0cb8 | [{"name":"General","history":[]}]
2 | 1 | Mark Cremin | http://lorempixel.com/640/480/sports | 59deabee-0df0-43c7-bf23-00d38eee3745 | [{"name":"General","history":[]}]
3 | 2 | Enoch Bartoletti | http://lorempixel.com/640/480/abstract | 765262a4-c855-412b-b496-c2d020a37e70 | [{"name":"General","history":[]}]
(3 rows)
node-sequelize-examples=# select * from "Server_User";
userId | serverId
--------+----------
1 | 1
1 | 2
2 | 3
(3 rows)
node-sequelize-examples=# select * from "user";
id | username | password | email
----+-----------------+-----------------+------------------------
1 | Reyes Botsford | 7p3cEWYkpxdZM0v | Robb.Weber@hotmail.com
2 | Micaela Kessler | G0qsV0FKNIDxAbA | Kiera66@yahoo.com
(2 rows)
关于node.js - 每当我尝试在 2 个模型之间创建多对多关联时,都必须为多对多自关联错误定义“as”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63005477/