gpt4 book ai didi

node.js - Sequelize 5 : TypeError on many-to-many methods

转载 作者:行者123 更新时间:2023-12-03 22:21:20 25 4
gpt4 key购买 nike

我正在使用 Sequelize 5.21.7(在 next.js 应用程序中)尝试在 Image 和 Tag 模型之间建立多对多关系,但是在尝试使用 imageInstance.addTag()imageInstance.getTags() 方法(以及与其他 _Tag[s]() 方法)。

// Tag.ts
import Sequelize, { DataTypes, Model } from 'sequelize';
import sequelize from '../instance';

class Tag extends Model {
id!: string;

title!: string;
}

Tag.init(
{
id: {
type: DataTypes.UUID,
defaultValue: Sequelize.UUIDV4,
primaryKey: true,
},
title: {
type: DataTypes.STRING,
unique: true,
},
},
{
sequelize,
modelName:'tag',
},
);


export default Tag;
// Image.ts
import Sequelize, {
DataTypes,
BelongsToManyAddAssociationMixin,
BelongsToManyCountAssociationsMixin,
BelongsToManyCreateAssociationMixin,
BelongsToManyGetAssociationsMixin,
BelongsToManyHasAssociationMixin,
BelongsToManyRemoveAssociationMixin,
BelongsToManySetAssociationsMixin,
Model,
Association,
} from 'sequelize';
import sequelize from '../instance';
import { Tag } from '../index';

class Image extends Model {
id!: string;

fileName!: string;

title: string;

Tags: Tag[];

public getTags!: BelongsToManyGetAssociationsMixin<Tag>;
public addTag!: BelongsToManyAddAssociationMixin<Tag, number>;
public setTags!: BelongsToManySetAssociationsMixin<Tag, number>;
public hasTag!: BelongsToManyHasAssociationMixin<Tag, number>;
public removeTag!: BelongsToManyRemoveAssociationMixin<Tag, number>;
public countTags!: BelongsToManyCountAssociationsMixin;
public createTag!: BelongsToManyCreateAssociationMixin<Tag>;

public static associations: {
tags: Association<Image, Tag>;
};
}

Image.init(
{
id: {
type: DataTypes.UUID,
defaultValue: Sequelize.UUIDV4,
primaryKey: true,
},
fileName: {
type: DataTypes.STRING,
},
title: {
type: DataTypes.STRING,
},
},
{
sequelize,
modelName: 'image',
},
);

export default Image;
// index.ts
import instance from './instance';
import Image from './models/Image';
import Tag from './models/Tag';

const ImageTags = Image.belongsToMany(Tag, {
through: 'ImageTags',
});
const TagImages = Tag.belongsToMany(Image, {
through: 'ImageTags',
});

instance.sync();

export default instance;
export { Image, ImageTags, Tag, TagImages };
// instance.ts
import { Sequelize } from 'sequelize';
import path from 'path';
import fs from 'fs';

const dbDirectory = path.resolve('data/db');
const storage = path.resolve(dbDirectory, 'gallery.sqlite');

if (!fs.existsSync(dbDirectory)) {
fs.mkdirSync(dbDirectory);
}
if (!fs.existsSync(storage)) {
fs.writeFileSync(storage, '');
}

const sequelize = new Sequelize({
dialect: 'sqlite',
storage,
});

export default sequelize;

我尝试使用的代码示例:
import { Image as ImageModel, Tag as TagModel } from 'path/to/db';

async function createImage(file) {
const image = await ImageModel.create<ImageModel>(
{
fileName: file.name,
title: file.name.replace(/\.[a-z]*$/, ''),
},
);
const tag = await TagModel.findOrCreate({ title: 'Untagged' });
image.addTag(tag); // TypeError: image.addTag is not a function
}

async function getImage(id) {
const image = await ImageModel.findByPk(id, { include: [ TagModel ] });
const tags = image.getTags(); // TypeError: image.getTags is not a function
}

我已经搜索了很多不同的 StackOverflow 问题,我可以在 as 调用中找到使用 belongsToMany 的其他问题,但我的示例没有。

最佳答案

它按预期工作。例如。
tag.ts :

import { sequelize } from '../../db';
import Sequelize, { Model, DataTypes } from 'sequelize';

class Tag extends Model {
id!: string;
title!: string;
}
Tag.init(
{
id: {
type: DataTypes.UUID,
defaultValue: Sequelize.UUIDV4,
primaryKey: true,
},
title: {
type: DataTypes.STRING,
unique: true,
},
},
{ sequelize, modelName: 'tag' },
);

export default Tag;
image.ts :

import { sequelize } from '../../db';
import Sequelize, {
Model,
DataTypes,
BelongsToManyGetAssociationsMixin,
BelongsToManyAddAssociationMixin,
BelongsToManySetAssociationsMixin,
BelongsToManyHasAssociationMixin,
BelongsToManyRemoveAssociationMixin,
BelongsToManyCountAssociationsMixin,
BelongsToManyCreateAssociationMixin,
Association,
} from 'sequelize';
import Tag from './tag';

class Image extends Model {
id!: string;
fileName!: string;
title!: string;
Tags!: Tag[];

public getTags!: BelongsToManyGetAssociationsMixin<Tag>;
public addTag!: BelongsToManyAddAssociationMixin<Tag, number>;
public setTags!: BelongsToManySetAssociationsMixin<Tag, number>;
public hasTag!: BelongsToManyHasAssociationMixin<Tag, number>;
public removeTag!: BelongsToManyRemoveAssociationMixin<Tag, number>;
public countTags!: BelongsToManyCountAssociationsMixin;
public createTag!: BelongsToManyCreateAssociationMixin<Tag>;

public static associations: {
tags: Association<Image, Tag>;
};
}
Image.init(
{
id: {
type: DataTypes.UUID,
defaultValue: Sequelize.UUIDV4,
primaryKey: true,
},
fileName: {
type: DataTypes.STRING,
},
title: {
type: DataTypes.STRING,
},
},
{ sequelize, modelName: 'image' },
);

export default Image;
index.ts :

import Image from './image';
import Tag from './tag';
import { sequelize } from '../../db';

const ImageTags = Image.belongsToMany(Tag, {
through: 'ImageTags',
});
const TagImages = Tag.belongsToMany(Image, {
through: 'ImageTags',
});

export default sequelize;
export { Image, ImageTags, Tag, TagImages };
main.ts :

import sequelize, { Image as ImageModel, Tag as TagModel } from './';

async function createImage(file) {
const image = await ImageModel.create<ImageModel>({
fileName: file.name,
title: file.name.replace(/\.[a-z]*$/, ''),
});
const [tag, created] = await TagModel.findOrCreate({ where: { title: 'Untagged' } });
await image.addTag(tag);
return image.id;
}

async function getImage(id) {
const image = await ImageModel.findByPk(id, { include: [TagModel] });
return image.getTags();
}

(async function test() {
try {
await sequelize.sync({ force: true });
const file = { name: 'avatar.jpg' };
const imageId = await createImage(file);
const tags = await getImage(imageId);
console.log('tags:', tags);
} catch (error) {
console.log(error);
} finally {
sequelize.close();
}
})();

执行结果:

Executing (default): DROP TABLE IF EXISTS "ImageTags" CASCADE;
Executing (default): DROP TABLE IF EXISTS "tag" CASCADE;
Executing (default): DROP TABLE IF EXISTS "image" CASCADE;
Executing (default): DROP TABLE IF EXISTS "image" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "image" ("id" UUID , "fileName" VARCHAR(255), "title" 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 = 'image' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): DROP TABLE IF EXISTS "tag" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "tag" ("id" UUID , "title" VARCHAR(255) 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 = 'tag' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): DROP TABLE IF EXISTS "ImageTags" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "ImageTags" ("imageId" UUID REFERENCES "image" ("id") ON DELETE CASCADE ON UPDATE CASCADE, "tagId" UUID REFERENCES "tag" ("id") ON DELETE CASCADE ON UPDATE CASCADE, PRIMARY KEY ("imageId","tagId"));
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 = 'ImageTags' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): INSERT INTO "image" ("id","fileName","title") VALUES ($1,$2,$3) RETURNING *;
Executing (220d292c-0ca9-4346-a530-ec18f45ec494): START TRANSACTION;
Executing (220d292c-0ca9-4346-a530-ec18f45ec494): SELECT "id", "title" FROM "tag" AS "tag" WHERE "tag"."title" = 'Untagged';
Executing (220d292c-0ca9-4346-a530-ec18f45ec494): CREATE OR REPLACE FUNCTION pg_temp.testfunc(OUT response "tag", OUT sequelize_caught_exception text) RETURNS RECORD AS $func_ce264c0247834fcfabde8a9190c361c9$ BEGIN INSERT INTO "tag" ("id","title") VALUES ('2f081666-958d-4513-b566-3d791817492c','Untagged') RETURNING * INTO response; EXCEPTION WHEN unique_violation THEN GET STACKED DIAGNOSTICS sequelize_caught_exception = PG_EXCEPTION_DETAIL; END $func_ce264c0247834fcfabde8a9190c361c9$ LANGUAGE plpgsql; SELECT (testfunc.response).*, testfunc.sequelize_caught_exception FROM pg_temp.testfunc(); DROP FUNCTION IF EXISTS pg_temp.testfunc();
Executing (220d292c-0ca9-4346-a530-ec18f45ec494): COMMIT;
Executing (default): SELECT "imageId", "tagId" FROM "ImageTags" AS "ImageTags" WHERE "ImageTags"."imageId" = '1519daf9-42e2-4d39-bc84-d0869107bb72' AND "ImageTags"."tagId" IN ('2f081666-958d-4513-b566-3d791817492c');
Executing (default): INSERT INTO "ImageTags" ("imageId","tagId") VALUES ('1519daf9-42e2-4d39-bc84-d0869107bb72','2f081666-958d-4513-b566-3d791817492c') RETURNING *;
Executing (default): SELECT "image"."id", "image"."fileName", "image"."title", "tags"."id" AS "tags.id", "tags"."title" AS "tags.title", "tags->ImageTags"."imageId" AS "tags.ImageTags.imageId", "tags->ImageTags"."tagId" AS "tags.ImageTags.tagId" FROM "image" AS "image" LEFT OUTER JOIN ( "ImageTags" AS "tags->ImageTags" INNER JOIN "tag" AS "tags" ON "tags"."id" = "tags->ImageTags"."tagId") ON "image"."id" = "tags->ImageTags"."imageId" WHERE "image"."id" = '1519daf9-42e2-4d39-bc84-d0869107bb72';
Executing (default): SELECT "tag"."id", "tag"."title", "ImageTags"."imageId" AS "ImageTags.imageId", "ImageTags"."tagId" AS "ImageTags.tagId" FROM "tag" AS "tag" INNER JOIN "ImageTags" AS "ImageTags" ON "tag"."id" = "ImageTags"."tagId" AND "ImageTags"."imageId" = '1519daf9-42e2-4d39-bc84-d0869107bb72';
tags: [ tag {
dataValues:
{ id: '2f081666-958d-4513-b566-3d791817492c',
title: 'Untagged',
ImageTags: [ImageTags] },
_previousDataValues:
{ id: '2f081666-958d-4513-b566-3d791817492c',
title: 'Untagged',
ImageTags: [ImageTags] },
_changed: {},
_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: false,
_schema: null,
_schemaDelimiter: '',
include: [Array],
includeNames: [Array],
includeMap: [Object],
includeValidated: true,
attributes: [Array],
raw: true },
isNewRecord: false,
ImageTags:
ImageTags {
dataValues: [Object],
_previousDataValues: [Object],
_changed: {},
_modelOptions: [Object],
_options: [Object],
isNewRecord: false } } ]

检查数据库:

node-sequelize-examples=# select * from "ImageTags";
imageId | tagId
--------------------------------------+--------------------------------------
1519daf9-42e2-4d39-bc84-d0869107bb72 | 2f081666-958d-4513-b566-3d791817492c
(1 row)

node-sequelize-examples=# select * from tag;
id | title
--------------------------------------+----------
2f081666-958d-4513-b566-3d791817492c | Untagged
(1 row)

node-sequelize-examples=# select * from image;
id | fileName | title
--------------------------------------+------------+--------
1519daf9-42e2-4d39-bc84-d0869107bb72 | avatar.jpg | avatar
(1 row)

关于node.js - Sequelize 5 : TypeError on many-to-many methods,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61625287/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com