Sequelize ссылка на неправильный внешний ключ - PullRequest
0 голосов
/ 28 февраля 2020

Есть две таблицы, которые представляют собой транзакцию и детали транзакции. RecordId является внешним ключом деталей транзакции.

Я пытаюсь найти транзакцию по recordId, а затем включить детали транзакции. Транзакция может иметь много деталей транзакции. Вот мои коды:

db.models.Transaction.hasMany(db.models.TransactionDetails, {
    foreignKey: 'recordId'
});

А потом я запрашиваю findOne, и это выглядит так:

db.models.Transaction.findOne({
            where: {
                recordId: req.query.recordid
            } ,
            include: [{
                model: db.models.TransactionDetails
            }]

        })

Но когда я отправил запрос на Почтальон, JSON данные выглядели так:

{
"error": false,
"message": {
    "id": "8151",
    "recordId": "6688",
    "transactionNo": "1563804469415",
    "cashierId": "4",
    "payType": "cash",
    "terminalNo": "0012346",
    "amount": 40,
    "discount": 0,
    "cardNo": "none",
    "transDate": "2019-07-22T14:23:26.000Z",
    "createdAt": "2019-07-22T14:20:19.679Z",
    "updatedAt": "2019-07-22T14:20:19.679Z",
    "pt-transactions-details": [
        {
            "id": "38048",
            "recordId": "8151", //this is wrong, the recordId must be the same as above which is 6688
            "transId": "3731",
            "productId": "539",
            "quantity": "1",
            "amount": 60,
            "terminal": "002789",
            "createdAt": "2019-09-13T01:22:48.349Z",
            "updatedAt": "2019-09-13T01:22:48.349Z"
        },
        {
            "id": "9921",
            "recordId": "8151", //this is wrong, the recordId must be the same as above which is 6688
            "transId": "3985",
            "productId": "1061",
            "quantity": "2",
            "amount": 100,
            "terminal": "0012346",
            "createdAt": "2019-07-05T03:44:49.406Z",
            "updatedAt": "2019-07-05T03:44:49.406Z"
        },
        {
            "id": "68848",
            "recordId": "8151", //this is wrong, the recordId must be the same as above which is 6688
            "transId": "5358",
            "productId": "1128",
            "quantity": "1",
            "amount": 160,
            "terminal": "171412",
            "createdAt": "2019-10-15T13:00:03.864Z",
            "updatedAt": "2019-10-15T13:00:03.864Z"
        }
    ]
}

}

Может ли кто-нибудь помочь мне в этом? Я уже провел день, пытаясь понять это. Спасибо!

Ответы [ 2 ]

0 голосов
/ 28 февраля 2020

Короткий ответ, вам нужно передать sourceKey в hasMany метод.

Transaction.hasMany(TransactionDetail, { foreignKey: 'recordId', sourceKey: 'recordId' });

Длинный ответ, вот пример:

index.ts:

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

class Transaction extends Model {}
Transaction.init(
  {
    recordId: {
      unique: true,
      type: DataTypes.STRING,
    },
  },
  { sequelize, modelName: 'transactions' },
);

class TransactionDetail extends Model {}
TransactionDetail.init(
  {
    amount: DataTypes.INTEGER,
  },
  { sequelize, modelName: 'transaction_details' },
);

Transaction.hasMany(TransactionDetail, { foreignKey: 'recordId', sourceKey: 'recordId' });

(async function test() {
  try {
    await sequelize.sync({ force: true });
    await Transaction.create(
      { recordId: '6688', transaction_details: [{ amount: 60 }, { amount: 100 }, { amount: 160 }] },
      { include: [TransactionDetail] },
    );

    const rval = await Transaction.findOne({ where: { recordId: '6688' }, include: [TransactionDetail] });
    console.log(rval.dataValues);
    assert.equal(rval.transaction_details.length, 3, 'transaction details count should equal 3');
    const transactionDetailsDataValues = rval.transaction_details.map((d) => d.dataValues);
    console.log('transactionDetailsDataValues: ', transactionDetailsDataValues);
  } catch (error) {
    console.log(error);
  } finally {
    await sequelize.close();
  }
})();

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

{ id: 1,
  recordId: '6688',
  transaction_details:
   [ transaction_details {
       dataValues: [Object],
       _previousDataValues: [Object],
       _changed: {},
       _modelOptions: [Object],
       _options: [Object],
       isNewRecord: false },
     transaction_details {
       dataValues: [Object],
       _previousDataValues: [Object],
       _changed: {},
       _modelOptions: [Object],
       _options: [Object],
       isNewRecord: false },
     transaction_details {
       dataValues: [Object],
       _previousDataValues: [Object],
       _changed: {},
       _modelOptions: [Object],
       _options: [Object],
       isNewRecord: false } ] }
transactionDetailsDataValues:  [ { id: 1, amount: 60, recordId: '6688' },
  { id: 2, amount: 100, recordId: '6688' },
  { id: 3, amount: 160, recordId: '6688' } ]

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

node-sequelize-examples=# select * from "transactions";
 id | recordId
----+----------
  1 | 6688
(1 row)

node-sequelize-examples=# select * from "transaction_details";
 id | amount | recordId
----+--------+----------
  1 |     60 | 6688
  2 |    100 | 6688
  3 |    160 | 6688
(3 rows)

Версия Sequelize: "sequelize": "^5.21.3"

исходный код: https://github.com/mrdulin/node-sequelize-examples/tree/master/src/examples/stackoverflow/60446814

0 голосов
/ 28 февраля 2020

Вам необходимо определить связь Sequelize, как указано ниже -

db.models.Transaction.belongsTo(db.models.TransactionDetails, {
    foreignKey: 'recordId', targetKey: 'recordId'
});

Надеюсь, это поможет!

...