Sequelize.js - 如何访问关联的内存项目
Sequelize.js - How to access associated in-memory items
我有 2 个模型,一个称为 User,第二个称为 Preferences。
两者之间存在关联:
User.hasOne(Preferences)
假设 user 是 User 的一个实例并且 pref 是 Preferences 之一
还有这样的声明:
user.setPreferences(pref)
然后 AFAIU 用户和 pref 以某种方式链接(即使尚未存储在数据库中)。
然后,从用户的角度来看,我如何才能访问其关联的首选项。
使用 getPreferences() 将调用在这种情况下无用的数据库......
我检查了 user.preferences 和 user._preferences 但两者都未定义。
是否有一种简单的方法来处理相关项目?
user.Preferences
在代码中明确请求时填充,如下所示:
const user2: User = await User.findOne({ where: { id: 1 }, include: [Preference] });
console.log(user2.Preferences); // it's only populated when explicitly requested in code
它将SQL发送到数据库。否则,值为 undefined
.
最简单的方法是在 User
模型 class 上创建私有 属性 并在执行后为每个用户实例存储关联的 preferences
模型实例 user.setPreferences(pref)
没有调用 DB 就成功了。
例如使用 "sequelize": "^5.21.3"
import { sequelize } from '../../db';
import { Model, DataTypes, HasManyGetAssociationsMixin, HasManySetAssociationsMixin } from 'sequelize';
class User extends Model {
public id!: number;
public getPreferences!: HasManyGetAssociationsMixin<Preference>;
public setPreferences!: HasManySetAssociationsMixin<Preference, Preference['id']>;
public readonly Preferences?: Preference[];
public _inMemoryAssociatedPreferences: Preference[] = [];
}
User.init({}, { sequelize });
class Preference extends Model {
public id!: number;
public name!: string;
}
Preference.init({ name: DataTypes.STRING }, { sequelize });
User.hasMany(Preference);
Preference.belongsTo(User);
(async function test() {
await sequelize.sync({ force: true });
await User.create({ id: 1 });
const user: User = await User.findOne({ where: { id: 1 } });
const pref = await Preference.create({ id: 1, name: 'a' });
await user.setPreferences(pref);
user._inMemoryAssociatedPreferences = [pref];
// elsewhere
console.log('in memory preferences:', user._inMemoryAssociatedPreferences);
await sequelize.close();
})();
输出:
Executing (default): DROP TABLE IF EXISTS "Preference" 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 , 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 "Preference" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "Preference" ("id" SERIAL , "name" VARCHAR(255), "UserId" INTEGER REFERENCES "User" ("id") ON DELETE SET NULL ON UPDATE CASCADE, 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 = 'Preference' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): INSERT INTO "User" ("id") VALUES () RETURNING *;
Executing (default): SELECT "id" FROM "User" AS "User" WHERE "User"."id" = 1;
Executing (default): INSERT INTO "Preference" ("id","name") VALUES (,) RETURNING *;
Executing (default): SELECT "id", "name", "UserId" FROM "Preference" AS "Preference" WHERE "Preference"."UserId" = 1;
Executing (default): UPDATE "Preference" SET "UserId"= WHERE "id" IN (1)
in memory preferences: [
Preference {
dataValues: { id: 1, name: 'a', UserId: null },
_previousDataValues: { id: 1, name: 'a', UserId: null },
_changed: { id: false, name: false, UserId: false },
_modelOptions: {
timestamps: false,
validate: {},
freezeTableName: true,
underscored: false,
paranoid: false,
rejectOnEmpty: false,
whereCollection: [Object],
schema: null,
schemaDelimiter: '',
defaultScope: {},
scopes: {},
indexes: [],
name: [Object],
omitNull: false,
sequelize: [Sequelize],
hooks: {}
},
_options: {
isNewRecord: true,
_schema: null,
_schemaDelimiter: '',
attributes: undefined,
include: undefined,
raw: undefined,
silent: undefined
},
isNewRecord: false
}
]
我有 2 个模型,一个称为 User,第二个称为 Preferences。 两者之间存在关联:
User.hasOne(Preferences)
假设 user 是 User 的一个实例并且 pref 是 Preferences 之一 还有这样的声明:
user.setPreferences(pref)
然后 AFAIU 用户和 pref 以某种方式链接(即使尚未存储在数据库中)。 然后,从用户的角度来看,我如何才能访问其关联的首选项。 使用 getPreferences() 将调用在这种情况下无用的数据库...... 我检查了 user.preferences 和 user._preferences 但两者都未定义。
是否有一种简单的方法来处理相关项目?
user.Preferences
在代码中明确请求时填充,如下所示:
const user2: User = await User.findOne({ where: { id: 1 }, include: [Preference] });
console.log(user2.Preferences); // it's only populated when explicitly requested in code
它将SQL发送到数据库。否则,值为 undefined
.
最简单的方法是在 User
模型 class 上创建私有 属性 并在执行后为每个用户实例存储关联的 preferences
模型实例 user.setPreferences(pref)
没有调用 DB 就成功了。
例如使用 "sequelize": "^5.21.3"
import { sequelize } from '../../db';
import { Model, DataTypes, HasManyGetAssociationsMixin, HasManySetAssociationsMixin } from 'sequelize';
class User extends Model {
public id!: number;
public getPreferences!: HasManyGetAssociationsMixin<Preference>;
public setPreferences!: HasManySetAssociationsMixin<Preference, Preference['id']>;
public readonly Preferences?: Preference[];
public _inMemoryAssociatedPreferences: Preference[] = [];
}
User.init({}, { sequelize });
class Preference extends Model {
public id!: number;
public name!: string;
}
Preference.init({ name: DataTypes.STRING }, { sequelize });
User.hasMany(Preference);
Preference.belongsTo(User);
(async function test() {
await sequelize.sync({ force: true });
await User.create({ id: 1 });
const user: User = await User.findOne({ where: { id: 1 } });
const pref = await Preference.create({ id: 1, name: 'a' });
await user.setPreferences(pref);
user._inMemoryAssociatedPreferences = [pref];
// elsewhere
console.log('in memory preferences:', user._inMemoryAssociatedPreferences);
await sequelize.close();
})();
输出:
Executing (default): DROP TABLE IF EXISTS "Preference" 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 , 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 "Preference" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "Preference" ("id" SERIAL , "name" VARCHAR(255), "UserId" INTEGER REFERENCES "User" ("id") ON DELETE SET NULL ON UPDATE CASCADE, 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 = 'Preference' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): INSERT INTO "User" ("id") VALUES () RETURNING *;
Executing (default): SELECT "id" FROM "User" AS "User" WHERE "User"."id" = 1;
Executing (default): INSERT INTO "Preference" ("id","name") VALUES (,) RETURNING *;
Executing (default): SELECT "id", "name", "UserId" FROM "Preference" AS "Preference" WHERE "Preference"."UserId" = 1;
Executing (default): UPDATE "Preference" SET "UserId"= WHERE "id" IN (1)
in memory preferences: [
Preference {
dataValues: { id: 1, name: 'a', UserId: null },
_previousDataValues: { id: 1, name: 'a', UserId: null },
_changed: { id: false, name: false, UserId: false },
_modelOptions: {
timestamps: false,
validate: {},
freezeTableName: true,
underscored: false,
paranoid: false,
rejectOnEmpty: false,
whereCollection: [Object],
schema: null,
schemaDelimiter: '',
defaultScope: {},
scopes: {},
indexes: [],
name: [Object],
omitNull: false,
sequelize: [Sequelize],
hooks: {}
},
_options: {
isNewRecord: true,
_schema: null,
_schemaDelimiter: '',
attributes: undefined,
include: undefined,
raw: undefined,
silent: undefined
},
isNewRecord: false
}
]