使用 datamapper 从类中删除属性时删除数据库字段
我在 Sinatra 应用程序中使用 datamapper。我目前使用该命令
DataMapper.finalize.auto_upgrade!
来处理迁移。我有两个具有“has_n”和“belongs_to”关联的课程(艺术家和活动)。一个事件“属于”一位艺术家,而一位艺术家可以有许多与之关联的事件。
我通过删除控制模型中原始 one_to_many 关联的类定义的先前部分并将
has n, :artists, :through => Resource
关联添加到 Event 类和 Artist 类中,将关联更改为多对多关系。当我创建一个新事件时,会出现错误。
#<DataObjects::IntegrityError: events.artist_id may not be NULL
:artist_id 字段是两个类之间原始关联的遗迹。新的 Many_to_many 关联由 event.artists[i] 访问(其中“i”只是一个从 0 到关联艺术家数量 -1 的整数索引)。显然Artist类和Event类之间原来的关联方法还在吗?我的猜测是,解决这个问题的方法不仅仅是使用 datamapper 内置的 auto_upgrade 方法,而是编写显式迁移。如果有一种方法可以处理这种类型的数据库更改,并且 auto_upgrade 方法仍然有效,那就太好了!
如果您需要有关我的模型或任何内容的更多详细信息,请询问,我很乐意添加它们。
I am using datamapper in a Sinatra application. I currently use the command
DataMapper.finalize.auto_upgrade!
to handle the migrations. I had two Classes (Artists and Events) with a 'has_n' and 'belongs_to' association. An Event 'belonged_to' one Artist and an Artist could have many Events associated with it.
I changed the association to be a many_to_many relationship by deleting the previous parts of the class definition which governed the original one_to_many association in the models and adding
has n, :artists, :through => Resource
to the Event class and the corresponding code to the Artist class. When I make a new Event, an error is kicked off.
#<DataObjects::IntegrityError: events.artist_id may not be NULL
The :artist_id field is a relic of the original association between the two classes. The new many_to_many association is accessed by event.artists[i] (where 'i' is just an integer index going from 0 to the number of associated artists -1). Apparently the original association method between the Artist and Event classes is still there? My guess is the solution to this is to not just use the auto_upgrade method built into datamapper but rather to write an explicit migration. If there is a way to handle this type of change to a database and still have the auto_upgrade method work, that would be great!
If you need more details about my models or anything please ask and I'll gladly add them.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
根据我的经验,DataMapper 的
auto_upgrade
工作得不太好——或者,至少可以说,它没有按照我期望的方式工作。如果你想向你的模型添加一个新列,它会做它应该做的事情;尝试对列执行任何更复杂的操作,它可能不会按照您的预期运行。例如,如果您创建
String
类型的属性,则其初始长度为 50 个字符。如果您发现 50 个字符不足以容纳您的字符串,请添加:length =>; 100
到模型不足以使auto_upgrade
更改列的宽度。看来您偶然发现了另一个缺点,尽管有人可能会说,在您的情况下,DataMapper 的行为也许并没有那么糟糕(想想遗留数据库)。但事实是,当您更改关联时,
Event
的artist_id
列并未被删除,然后当您尝试保存Event< /code>,你会得到一个错误,因为数据库说它是必填字段。
请注意,您收到的错误不是验证错误:DataMapper 认为一切看起来都正常,但在尝试保存对象时从数据库收到错误。
希望这有帮助!
In my experience, DataMapper's
auto_upgrade
does not work very well -- or, to say the least, it doesn't work the way I expect it to. If you want to add a new column to your model, it will do what it should; try to do anything more sophisticated to a column and it probably won't behave as you expect.For example, if you create a property of type
String
, it will initially have a length of 50 characters. If you notice that 50 characters is not enough to hold your string, adding:length => 100
to the model won't be enough to makeauto_upgrade
change the column's width.It seems you have stumbled upon another shortcoming, although one may argue that, in your case, maybe DataMapper's behavior isn't that bad (think of legacy databases). But the fact is that, when you changed the association, the
Event
'sartist_id
column wasn't removed, and then when you try to save anEvent
, you'll get an error because the database says it is a required field.Notice that the error you are getting is not a validation error: DataMapper thinks everything looks ok, but gets an error from the database when trying to save the object.
Hope this helps!
自动升级根本不是缺点!我认为自动升级是 DataMapper 的一个便利功能。据我所知,它的唯一目的是为您添加列。因此,它对于快速启动项目以及管理测试和开发环境而无需编写迁移非常有用,但它不是对成熟的实时项目进行修改的最佳工具。
为此,DataMapper 确实有迁移!使用 dm-migrations gem。缺点是它们根本没有很好的记录。我实际上正在努力将我当前的项目更改为使用迁移,并且我希望为 dm-migrations github wiki 贡献一些说明。但如果您还没有准备好切换到迁移,您也可以使用 SQL 客户端手动更新列,然后继续对新列使用自动升级。这就是我的项目两年来一直在做的事情:)
Auto-upgrade is not a shortcoming at all! I think of auto-upgrade as a convenience feature of DataMapper. It's only intended purpose is to add columns for you as far as I know. So it is great for getting a project started quickly, and managing test and dev environments without having to write migrations, but not the best tool for making modifications to a mature, live project.
For that, DataMapper does have migrations! Use the dm-migrations gem. The shortcoming is that they are not very well documented... at all. I'm actually working on changing a current project of mine over to using migrations, and I hope to contribute some instructions to the dm-migrations github wiki. But if you aren't ready to switch to migrations, you can also just update columns manually using an SQL client, and then continue to use auto-upgrade for new columns. That's what I have been doing for 2 years on my project :)