英文:
How to maintain migration and schema in xorm?
问题
如何在xorm中进行迁移和模式维护?
type Version struct {
ID int64
Name string
}
engine.Sync(new(Version))
这段代码只会将xorm模型与数据库同步。但是在某些情况下,我需要进行数据迁移。是否有类似于Rails中的schema.rb和migrations的选项呢?
英文:
How to maintain migration and schema in xorm?
type Version struct {
ID int64
Name string
}
engine.Sync(new(Version))
This will only sync the xorm model with database.
But I need data migrations in some cases. Is there any option like rails schema.rb and migrations?
答案1
得分: 2
我知道这个问题已经有一段时间了,但最近我不得不研究一下关于这个问题的稀缺信息,所以我决定详细说明一下@Alex Yu的评论并发布我的研究结果。
确实,为了执行迁移,我们需要使用xorm/migrate包。
考虑添加两个表的初始迁移。
var migrations = []*migrate.Migration{
{
ID: "201608301400",
Migrate: func(tx *xorm.Engine) error {
return tx.Sync2(&Person{})
},
Rollback: func(tx *xorm.Engine) error {
return tx.DropTables(&Person{})
},
},
{
ID: "201608301430",
Migrate: func(tx *xorm.Engine) error {
return tx.Sync2(&Pet{})
},
Rollback: func(tx *xorm.Engine) error {
return tx.DropTables(&Person{})
},
},
}
我们可以按以下方式使用它
m := migrate.New(engine, &migrate.Options{
TableName: "migrations",
IDColumnName: "id",
}, migrations)
err = m.Migrate()
现在让我们想象一下当我们向Person表添加一个字段的情况。与我们明确告诉引擎添加列的方法相反,在这里我们只需再次同步我们的数据库。
此外,在我的研究中,我没有找到一种明确删除回滚列的方法,所以我建议使用原始的SQL语句。
现在迁移将如下所示。请注意,你的SQL语句可能会有所不同。
var migrations = []*migrate.Migration{
{
ID: "201608301400",
Migrate: func(tx *xorm.Engine) error {
return tx.Sync2(&Person{})
},
Rollback: func(tx *xorm.Engine) error {
return tx.DropTables(&Person{})
},
},
{
ID: "201608301430",
Migrate: func(tx *xorm.Engine) error {
return tx.Sync2(&Pet{})
},
Rollback: func(tx *xorm.Engine) error {
_, e := tx.QueryString("ALTER TABLE dbo.person DROP COLUMN IF EXISTS your_new_column")
return e
},
},
}
Xorm会跟踪已经执行的迁移,所以只会运行最后一个迁移。
英文:
I know it's been a while since the question asked but I've recently had to research over scarce information regarding the issue so I've decided to elaborate on @Alex Yu comment and post my findings.
Indeed in order to perform a migration, we need xorm/migrate package.
Consider initial migration which adds 2 tables.
var migrations = []*migrate.Migration{
{
ID: "201608301400",
Migrate: func(tx *xorm.Engine) error {
return tx.Sync2(&Person{})
},
Rollback: func(tx *xorm.Engine) error {
return tx.DropTables(&Person{})
},
},
{
ID: "201608301430",
Migrate: func(tx *xorm.Engine) error {
return tx.Sync2(&Pet{})
},
Rollback: func(tx *xorm.Engine) error {
return tx.DropTables(&Person{})
},
},
}
We can consume it as follows
m := migrate.New(engine, &migrate.Options{
TableName: "migrations",
IDColumnName: "id",
}, migrations)
err = m.Migrate()
Now let's imagine the scenario when we add a field to a table Person. Contrary to approach that one might find as default when we explicitly tell engine to add column, here we just sync our db once again.
Also upon my research I have not found a way to explicitly drop column on rollback so I suggest using raw SQL.
Now migration will look as below. Note that your SQL may vary.
var migrations = []*migrate.Migration{
{
ID: "201608301400",
Migrate: func(tx *xorm.Engine) error {
return tx.Sync2(&Person{})
},
Rollback: func(tx *xorm.Engine) error {
return tx.DropTables(&Person{})
},
},
{
ID: "201608301430",
Migrate: func(tx *xorm.Engine) error {
return tx.Sync2(&Pet{})
},
Rollback: func(tx *xorm.Engine) error {
return tx.DropTables(&Person{})
},
},
{
ID: "201608301460",
Migrate: func(tx *xorm.Engine) error {
return tx.Sync2(&Person{})
},
Rollback: func(tx *xorm.Engine) error {
_, e := tx.QueryString("ALTER TABLE dbo.person DROP COLUMN IF EXISTS your_new_column")
return e
},
},
}
Xorm keeps track of migrations that are alsready executed, so only the last one will be run.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论