#foreign-keys #sequelize.js
#внешние ключи #sequelize.js
Вопрос:
Я использую Sequelize.js с SQLite-database и столкнулся с вопросом с установкой значения для внешнего ключа. У меня есть следующий код:
const MessageModel = sequelize.define('MessageModel ', {
uuid: DataTypes.STRING,
authorId: DataTypes.STRING,
// ... other props
}, {});
const TodoModel = sequelize.define('TodoModel', {
ownerId: DataTypes.STRING,
status: {
type: DataTypes.STRING,
defaultValue: 'pending'
}
}, {});
TodoModel.belongsTo(MessageModel , {
foreignKey: {
name: 'messageId',
field: 'messageId',
allowNull: false
},
targetKey: 'uuid'
});
MessageModel.create({
uuid: 'testUUIDForExample'
// other props
}).then(message => {
console.log(`Message's created successful`);
TodoModel.create({
ownerId: 'id-string',
status: 'test-status',
messageId: 'testUUIDForExample'
})
})
Sequelize создает строку MessageModel в базе данных, но она падает при попытке сгенерировать TodoModel с этой ошибкой:
DatabaseError: SQLITE_ERROR: foreign key mismatch - "TodoModel" referencing "MessageModel "
at Query.formatError (C:Userslrsvoweb-developmentprojectsplatoon-web-electronnode_modulessequelizelibdialectssqlitequery.js:432:16)
at Query._handleQueryResponse (C:Userslrsvoweb-developmentprojectsplatoon-web-electronnode_modulessequelizelibdialectssqlitequery.js:77:18)
at afterExecute (C:Userslrsvoweb-developmentprojectsplatoon-web-electronnode_modulessequelizelibdialectssqlitequery.js:260:31)
at Statement.errBack (C:Userslrsvoweb-developmentprojectsplatoon-web-electronnode_modulessqlite3libsqlite3.js:16:21)
Err.original.message: "SQLITE_ERROR: foreign key mismatch - "TodoModel" referencing "MessageModel"
Сгенерированный SQL:
"ВСТАВИТЬ В `TodoModel` (`id`,`OwnerId`,`status`, `createdAt`,`updatedAt`, `MessageId`) ЗНАЧЕНИЯ (NULL,$1,$2,$3,$4,$5);"
Моя таблица TodoModel выглядит следующим образом:
СОЗДАЙТЕ ТАБЛИЦУ "TodoModel" ( АВТОИНКРЕМЕНТ ПЕРВИЧНОГО КЛЮЧА с ЦЕЛЫМ числом "id", Переменная "OwnerId" (255), ТЕКСТ "статус" ПО УМОЛЧАНИЮ "ожидает", Дата-ВРЕМЯ "createdAt" НЕ РАВНА НУЛЮ, Дата-ВРЕМЯ "updatedAt" НЕ равна НУЛЮ, Параметр "MessageId" VARCHAR(255) НЕ равен НУЛЮ, ВНЕШНИЙ КЛЮЧ ("MessageId") ССЫЛАЕТСЯ НА "MessageModel" ("uuid") ПРИ УДАЛЕНИИ, НЕТ ДЕЙСТВИЙ При КАСКАДНОМ ОБНОВЛЕНИИ );
Я не могу понять, почему возникает ошибка, и мне нужна помощь, потому что я фиктивный в этом ORM.
Я использую «sequelize»: «^ 5.1.0» с SQLite.
Файл MyConfig:
const Sequelize = require("sequelize");
const electron = require('electron');
const storagePath = electron.app.getPath('userData') '/plt.db';
module.exports = {
development: {
dialect: "sqlite",
storage: storagePath,
username: null,
password: null,
operatorsAliases: Sequelize.Op,
define: { freezeTableName: true },
query: { raw: true }, // Always get raw result
logging: true,
},
};
Ответ №1:
Здесь есть несколько вещей. Во-первых, если вы собираетесь использовать uuid
в MessageModel в качестве первичного ключа, вы должны определить его, иначе у вас будет поле по умолчанию id
.
const MessageModel = sequelize.define('MessageModel ', {
uuid:{ // if this is your primary key you have to define it
type: DataTypes.STRING, //there is also DataTypes.UUID
allowNull: false,
primaryKey: true,
unique: true
},
authorId: DataTypes.STRING,
// ... other props
}, {});
Затем в вашей TodoModel вы устанавливаете messageId
ассоциацию как целое число. Чтобы изменить его на string, вы должны определить поле в модели, а в ассоциации использовать его в качестве внешнего ключа.
const TodoModel = sequelize.define('TodoModel', {
ownerId: DataTypes.STRING,
status: {
type: DataTypes.STRING,
defaultValue: 'pending'
},
messageId: { //you also have to add the field on your model and set it as STRING, because on the association Sequelize by default is going to use INTEGER
type: DataTypes.STRING,
allowNull: false
}
}, {});
TodoModel.belongsTo(MessageModel , {
as: 'Message',
foreignKey: 'messageId', // and you only set the foreignKey - Same name as your field above
});