Sequelize 迁移中的关联
Posted
技术标签:
【中文标题】Sequelize 迁移中的关联【英文标题】:Associations in Sequelize migrations 【发布时间】:2016-01-27 10:29:00 【问题描述】:我的应用目前使用 Sequelize sync()
方法创建数据库,我想将其更改为使用迁移系统。
我的一个模型与其他模型有belongsTo()
关联,我真的不知道如何为这些关联制作初始迁移代码。
我是否必须使用 SQL 查询手动创建外键,或者是否有一些可用的方法?
【问题讨论】:
您想使用迁移来创建初始数据库结构,或者您想使用迁移来更新您当前的数据库结构? 我要先创建初始数据库结构 【参考方案1】:案例 1:数据库初始化
如果您的目的是在数据库结构初始化期间添加关系,最好只使用sync
方法而不是使用迁移手动添加它们。如果您的模型设计正确并定义了关系,它们将在执行sync
方法期间自动创建。
看看sequelize express example。在模型目录中,您有三个文件:
index.js
- 包括所有型号
task.js
- 任务模型
user.js
- 用户模型
查看task.js
内容,从第 7 行开始,以下代码创建了 User 和 Task 模型之间的关系:
classMethods:
associate: function(models)
Task.belongsTo(models.User,
onDelete: "CASCADE",
foreignKey:
allowNull: false
);
如果您在模型文件中正确准备了关系,同步将为您创建外键。在这种情况下不需要迁移。
我鼓励您阅读整个 express-example readme.md
并浏览存储库文件以了解这些内容如何与 express 和 sequelize 一起使用。
案例2:数据库结构迁移
如果您已经有一些想要保留的数据,则需要使用迁移脚本,因为同步重构数据库的唯一方法是将其与所有数据一起完全销毁。
您可以阅读基本的migrations in the sequelize docs。不幸的是,文档不包括创建关系。假设您要创建以下关系:用户属于组。要在关系的用户端创建列,您可以使用addColumn
方法。
queryInterface.addColumn(
'user',
'group_id',
type: Sequelize.INTEGER,
allowNull: true
)
不幸的是,还没有一个很好的函数来为您创建外键约束,但您可以使用 sequelize 查询方法手动完成。 Postgresql 示例:
queryInterface.sequelize.query("ALTER TABLE user
ADD CONSTRAINT user_group_id_fkey FOREIGN KEY (group_id)
REFERENCES group (id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE;");
编辑:添加数据库结构迁移案例
【讨论】:
嗯,好的,谢谢。我想我对迁移和同步之间的差异以及何时使用它们感到有些困惑。因此,如果我只使用 sync() 更新我的模型,它会正确迁移我的数据库吗? Sync 根据您当前的模型创建一个干净的数据库结构。如果 force 属性设置为 false,它只会在数据库不存在时创建数据库。否则每次重新启动服务器时它都会擦除整个数据库。迁移脚本用于通过对现有结构和数据进行操作来更改现有数据库。它在您希望在更新之间保留数据的生产环境中很有用。 投反对票,因为问题是专门关于迁移(生产需要),而这个答案没有回答这个问题。 (但sync
的答案很好)。
@ezrepotein 是的,这就是我目前正在做的事情。感谢您更新您的答案。非常讨厌我们必须这样做,功能在那里,但我不太确定如何将它拉出来。如果我找到更好的解决方案会回复。
从 17 年 5 月开始,您可以在迁移中创建外键约束。见这里:github.com/sequelize/cli/issues/239#issuecomment-166564364【参考方案2】:
将其添加为答案而不是上述@aryeh-armon 答案的评论(没有足够的代表)。这是您需要确保存在的表名,而不是模型名。即,如果您的模型名为 Job 并且您的 db 表名为 Jobs,那么迁移将看起来像这样。
jobId:
type: Sequelize.INTEGER,
references:
model: "Jobs",
key: "id"
,
【讨论】:
这是对 aryeh armon 答案的澄清(我同意,应该是评论),但我还没有足够的代表来评论其他用户的答案。【参考方案3】:您可以添加对迁移的引用
示例:
user_id:
type: Sequelize.BIGINT,
references:
model: "users",
key: "id"
,
只要确保您引用的模型存在即可。
【讨论】:
【参考方案4】:经过大量搜索,我找到了几篇解释我想做的博客文章。第一个已经不存在了,here's the second one
显然这不是真正的常用方法,但对我来说似乎更合乎逻辑。如果您只想使用迁移,则必须使用 SQL 查询来创建初始迁移。
但无论如何,我认为 ezpn 是正确的,它使用同步创建初始数据库,然后迁移。它似乎比使用 umzug 更容易并且只使用迁移。
【讨论】:
我同意最后一句话之前的一切。您需要迁移生产代码。 您能否详细说明使用迁移在生产环境中初始化数据库的可能用例? @ezrepotein sync 非常适合创建数据库,显然只是问题标题用更一般的(因此有用的)“Sequelize 迁移中的关联”来表述。我实际上更喜欢在生产中使用迁移,如果你也为你的测试数据库这样做,为什么不这样做。然后您的数据库设置和更新使用相同的声明性命令,例如sequelize db:migrate
,而不是一些if no db, then db:sync, otherwise db:migrate
之类的东西。我认为人们普遍认为前者优于后者。
您描述的那些链接现在变成垃圾邮件,并重定向到随机页面!.
@user8969730 谢谢!我认为第一个丢失了,但第二个 URL 似乎略有不同。自从我从事这个项目以来已经很长时间了,所以我无法描述我当时所做的事情,我能做的最好的就是更新链接,对不起。这可能已经过时了,请检查其他答案的 cmets。以上是关于Sequelize 迁移中的关联的主要内容,如果未能解决你的问题,请参考以下文章