#node.js #sequelize.js
Вопрос:
Я пытаюсь создать 2 таблицы с отношениями один к одному.
- Заказы (из которых идентификатор является первичным ключом)
- Сроки действия (которые будут относиться к заказу)
Не у всех заказов истечет срок действия, но у всех заказов истечет срок действия.
Используя браузер БД для SQLite, я вижу, что 2 таблицы созданы и выглядят нормально. Все данные вводятся в таблицу Заказов без проблем. Однако при попытке добавить данные в таблицу истечения срока действия это приводит к ошибке ограничения внешнего ключа, которая не очень полезна:
{ parent: [Error: SQLITE_CONSTRAINT: FOREIGN KEY constraint failed] { errno: 19, code: 'SQLITE_CONSTRAINT', sql: 'INSERT INTO `SUP_expiries` (`id`,`merchantId`,`expiredDate`,`expiredAmt`,`createdAt`,`updatedAt`,`OrderId`) VALUES (NULL,$1,$2,$3,$4,$5,$6);' } }
Я думаю, что это как-то связано с тем, что я пытаюсь добавить значения внешнего ключа, но я не могу этого понять. У меня уже есть все идентификаторы в csv, чтобы связать сроки действия с заказами. Полный код приведен ниже, любая помощь будет очень признательна!
var fs = require('fs') var csv = require('csv-parser') var moment = require('moment') const { Sequelize, DataTypes, FLOAT } = require('sequelize') const sequelize = new Sequelize({ dialect: 'sqlite', storage: 'data.db', logging: false, query: { raw: true } }) const Order = sequelize.define('Order', { id: { type: DataTypes.INTEGER, primaryKey: true, }, merchantId: DataTypes.INTEGER, merchantName: DataTypes.STRING, orderAmt: DataTypes.INTEGER, orderDate: DataTypes.DATEONLY, expiryDate: DataTypes.DATEONLY }, { tableName: 'SUP_orders' }) const Expiry = sequelize.define('Expiry', { merchantId: DataTypes.INTEGER, expiredDate: DataTypes.DATEONLY, expiredAmt: DataTypes.INTEGER, }, { tableName: 'SUP_expiries' }) Order.hasOne(Expiry) Expiry.belongsTo(Order) function addOrders() { return new Promise((resolve) => { const data = [] fs.createReadStream('SUP_orders.csv').pipe(csv()).on('data', (row) => { let orderDate = moment(row.order_date).format('YYYY-MM-DD') data.push({ id: row.order_id, merchantId: row.merchant_id, merchantName: row.merchant_name, orderAmt: row.order_amount, orderDate: orderDate, expiryDate: moment(orderDate).add(19, 'days') }) }).on('end', () => { Order.bulkCreate(data, { validate: true }) resolve() }) }) } function addExpiries() { return new Promise((resolve) => { fs.createReadStream('SUP_expiries.csv').pipe(csv()).on('data', (row) => { Expiry.create({ merchantId: row.merchant_id, OrderId: row.order_id, expiredDate: moment(row.expire_date).format('YYYY-MM-DD'), expiredAmt: row.expired_sum }) }).on('end', () => { resolve() }) }) } async function main() { try { await sequelize.sync({force: true}) await addOrders() await addExpiries() } catch (err) { console.log(err) } } main()
Ответ №1:
отношение в приведенном выше коде
Order.hasOne(Expiry) Expiry.belongsTo(Order)
Для истечения срока действия такого отношения должно быть поле orderid
и установлено allowNull
в значение true. не таблица заказов должна иметь срок действия.