Как найти атрибут родительской таблицы с внешним ключом из дочерней таблицы - PullRequest
0 голосов
/ 05 марта 2020

Я только начал использовать sequelize в своем проекте и в настоящее время создал две таблицы, подобные этой:

const Blogpost = sequelize.define('blogposts', {
    blogId: {
        type: Sequelize.INTEGER,
        allowNull: false,
        primaryKey: true,
        autoIncrement: true
    },
    title: Sequelize.TEXT,
    content: Sequelize.TEXT,
    posted: Sequelize.TEXT,
    imageFile: Sequelize.TEXT
    }, {
    timestamps: false
})

Blogpost.sync().then(() => {
    console.log("Blogposts table created!")
})

const Account = sequelize.define('accounts', {
    personId: {
        type: Sequelize.INTEGER,
        allowNull: false,
        primaryKey: true,
        autoIncrement: true
    },
    username: {
        type: Sequelize.STRING(50),
        allowNull: false,
        unique: true
    },
    email: {
        type: Sequelize.STRING(50),
        allowNull: false,
        unique: true
    },
    userPassword: Sequelize.TEXT
    }, {
    timestamps: false
})

Blogpost.belongsTo(Account, {foreignKey: "userId", foreignKeyConstraint: true})

Account.sync().then(() => {
    console.log("Accounts table created!")
})

Теперь я хочу получить имя пользователя из учетных записей таблицы с userId из таблицы blogpost , вот как я хочу, чтобы она была такой:

getUsernameById: function(userId, callback){
        //retrieve username
        }).then(function(username){
            console.log("usernameSQE:", username)
            callback(username, [])
        }).catch(function(errors){
            console.log(errors)
            callback(null, errors)
        })
}

Как можно Я совершил sh это?

Заранее спасибо!

1 Ответ

1 голос
/ 09 марта 2020

Sequelize версия: "sequelize": "^5.21.3". Вот завершенный рабочий пример:

index.js:

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

const Blogpost = sequelize.define(
  'blogposts',
  {
    blogId: {
      type: Sequelize.INTEGER,
      allowNull: false,
      primaryKey: true,
      autoIncrement: true,
    },
    title: Sequelize.TEXT,
    content: Sequelize.TEXT,
    posted: Sequelize.TEXT,
    imageFile: Sequelize.TEXT,
  },
  {
    timestamps: false,
  },
);

const Account = sequelize.define(
  'accounts',
  {
    personId: {
      type: Sequelize.INTEGER,
      allowNull: false,
      primaryKey: true,
      autoIncrement: true,
    },
    username: {
      type: Sequelize.STRING(50),
      allowNull: false,
      unique: true,
    },
    email: {
      type: Sequelize.STRING(50),
      allowNull: false,
      unique: true,
    },
    userPassword: Sequelize.TEXT,
  },
  {
    timestamps: false,
  },
);

Blogpost.belongsTo(Account, { foreignKey: 'userId', foreignKeyConstraint: true });

function getUsernameById(userId, callback) {
  return Blogpost.findOne({
    where: {
      userId: {
        [Op.eq]: userId,
      },
    },
    include: [{ model: Account, attributes: ['username'] }],
  })
    .then((blogpost) => blogpost.account.username)
    .then(function(username) {
      callback(username, []);
    })
    .catch(function(errors) {
      console.log(errors);
      callback(null, errors);
    });
}

(async function test() {
  try {
    await sequelize.sync({ force: true });
    // seed
    await Blogpost.create(
      {
        title: 'some title',
        content: 'some content',
        posted: 'some posted',
        imageFile: 'dog.jpg',
        account: { username: 'steam', email: 'example@gmail.com', userPassword: '123456' },
      },
      { include: [Account] },
    );

    // test
    await getUsernameById(1, (username) => {
      console.log('username: ', username);
    });
  } catch (error) {
    console.log(error);
  } finally {
    await sequelize.close();
  }
})();

Результаты выполнения:

Executing (default): DROP TABLE IF EXISTS "blogposts" CASCADE;
Executing (default): DROP TABLE IF EXISTS "accounts" CASCADE;
Executing (default): DROP TABLE IF EXISTS "accounts" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "accounts" ("personId"   SERIAL , "username" VARCHAR(50) NOT NULL UNIQUE, "email" VARCHAR(50) NOT NULL UNIQUE, "userPassword" TEXT, PRIMARY KEY ("personId"));
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 = 'accounts' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): DROP TABLE IF EXISTS "blogposts" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "blogposts" ("blogId"   SERIAL , "title" TEXT, "content" TEXT, "posted" TEXT, "imageFile" TEXT, "userId" INTEGER REFERENCES "accounts" ("personId") ON DELETE SET NULL ON UPDATE CASCADE, PRIMARY KEY ("blogId"));
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 = 'blogposts' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): INSERT INTO "accounts" ("personId","username","email","userPassword") VALUES (DEFAULT,$1,$2,$3) RETURNING *;
Executing (default): INSERT INTO "blogposts" ("blogId","title","content","posted","imageFile","userId") VALUES (DEFAULT,$1,$2,$3,$4,$5) RETURNING *;
Executing (default): SELECT "blogposts"."blogId", "blogposts"."title", "blogposts"."content", "blogposts"."posted", "blogposts"."imageFile", "blogposts"."userId", "account"."personId" AS "account.personId", "account"."username" AS "account.username" FROM "blogposts" AS "blogposts" LEFT OUTER JOIN "accounts" AS "account" ON "blogposts"."userId" = "account"."personId" WHERE "blogposts"."userId" = 1 LIMIT 1;
username:  steam

Проверка записей данных в базе данных:

node-sequelize-examples=# select * from "accounts";
 personId | username |       email       | userPassword
----------+----------+-------------------+--------------
        1 | steam    | example@gmail.com | 123456
(1 row)

node-sequelize-examples=# select * from "blogposts";
 blogId |   title    |   content    |   posted    | imageFile | userId
--------+------------+--------------+-------------+-----------+--------
      1 | some title | some content | some posted | dog.jpg   |      1
(1 row)
...