最新消息: 电脑我帮您提供丰富的电脑知识,编程学习,软件下载,win7系统下载。

Sequelize 5:多对多方法中的TypeError

IT培训 admin 12浏览 0评论

Sequelize 5:多对多方法中的TypeError

[我正在使用Sequelize 5.21.7(在next.js应用程序中)尝试在图像和标签模型之间建立多对多关系,但是在尝试使用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)

Sequelize 5:多对多方法中的TypeError

[我正在使用Sequelize 5.21.7(在next.js应用程序中)尝试在图像和标签模型之间建立多对多关系,但是在尝试使用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)
发布评论

评论列表 (0)

  1. 暂无评论