浏览 5754 次
锁定老帖子 主题:rake test_units删除表的问题
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2006-10-07
不过这个过程有些问题,它是删除一个表,然后马上就重建。 这样的话,如果被删除的表,还有一个父表存在,就不能被删除。重建过程也会失败。 test_units就运行失败了。失败就失败吧,可是test_units的结果都没有显示出来,郁闷. 能不能把这个过程修改下,改成先删除全部的表,然后再重建所有表。这样的过程就不会受各种FK影响了。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2006-10-08
用rake db:test:purge可以强制删掉所有表。Rails对外键不是太友好,特别是fixture。
|
|
返回顶楼 | |
发表时间:2006-10-08
cookoo 写道 用rake db:test:purge可以强制删掉所有表。Rails对外键不是太友好,特别是fixture。
强制删除表的问题还好。关键是rake test_units的结果看不到了.想修正下rake test_units最后的那个删除和重建过程,有没有办法?至少让我看下test_units的结果。 如果rake改不了这个,只好自己写脚本了.一个一个的运行ruby ...test.rb,也是够麻烦的 |
|
返回顶楼 | |
发表时间:2006-10-08
我还是不太明白你说的是表还是表里的记录?
test:units会先执行db:test:prepare,后者根据environment里的schema格式设定判断是调用db:test:clone_structure(SQL方式)或者db:test:clone(ruby dsl方式)。后一种方式比较简单,就是dump出来再load到test数据库,忽略外键。前一种对不同数据库操作略有不同,对mysql来说它会先执行db:test:purge删除整个数据库(不是一个一个删表)再重建,然后导入schema的时候会关掉外键检查。绕来绕去,也就是test:units重建test数据库表结构不会受到外键影响。 外键可能会造成问题的是fixture的数据导入。对mysql修改比较傻瓜,在test_helper.rb里加 class Fixtures # Oh for alias_method_chain alias :original_delete_existing_fixtures :delete_existing_fixtures alias :original_insert_fixtures :insert_fixtures def delete_existing_fixtures @connection.update "SET FOREIGN_KEY_CHECKS = 0", 'Fixtures deactivate foreign key checks.'; original_delete_existing_fixtures @connection.update "SET FOREIGN_KEY_CHECKS = 1", 'Fixtures activate foreign key checks.'; end def insert_fixtures @connection.update "SET FOREIGN_KEY_CHECKS = 0", 'Fixtures deactivate foreign key checks.'; original_insert_fixtures @connection.update "SET FOREIGN_KEY_CHECKS = 1", 'Fixtures activate foreign key checks.'; end end |
|
返回顶楼 | |
发表时间:2006-10-09
cookoo 写道 对mysql来说它会先执行db:test:purge删除整个数据库(不是一个一个删表)再重建 执行test_units时,察看了下mysql的sql语句执行过程,很明显的,是先drop table 然后再create table,create index. 每一个表都是这样的执行过程。 然后有张表 先drop,create时,提示表已经存在.也就是前面的drop 根本没有成功.但是没有报错,到了create时才出错. |
|
返回顶楼 | |
发表时间:2006-10-09
我总算复制出你的错误了。问题是你混用了sql和ruby dsl两种schema方式。根据前一篇帖子,你的test数据库用db:test:clone_structure事先建立(其实不必),这个是sql方式,会复制development数据库中的外键。相反,在ruby dsl模式下的外键是被完全忽略的,即使开发数据库里有,也不会复制到test数据库里。
而test:units执行的时候是根据environment.rb里的config.active_record.schema_format = sql设置(注释掉时为ruby dsl模式)来判断用哪种模式的。通过使用rake test:units --trace我们可以看见两者的差别:(忽略invoke,只看execute) ruby dsl模式的schema下执行的task: ** Invoke test:units (first_time) ** Invoke db:test:prepare (first_time) ** Invoke environment (first_time) ** Execute environment ** Execute db:test:prepare ** Invoke db:test:clone (first_time) ** Invoke db:schema:dump (first_time) ** Invoke environment ** Execute db:schema:dump ** Execute db:test:clone ** Invoke db:schema:load (first_time) ** Invoke environment ** Execute db:schema:load ** Execute test:units ... sql模式的schema下执行的task: ** Invoke test:units (first_time) ** Invoke db:test:prepare (first_time) ** Invoke environment (first_time) ** Execute environment ** Execute db:test:prepare ** Invoke db:test:clone_structure (first_time) ** Invoke db:structure:dump (first_time) ** Invoke environment ** Execute db:structure:dump ** Invoke db:test:purge (first_time) ** Invoke environment ** Execute db:test:purge ** Execute db:test:clone_structure ** Execute test:units 具体的task内部代码就不展开讨论了,关键差别是sql模式知道有外键存在,所以多了一个db:test:purge直接删整个数据库而不管表顺序一一删除的操作。而ruby dsl模式假设没有外键,只是简单用load。load这个操作就是删一个再建一个的,这某种程度上是ruby dsl风格的schema的限制所致(必须顺序执行,不能事先检查外键依赖关系)。 所以解决办法就是:先purge掉test数据库,然后设好config.active_record.schema_format要外键的用sql格式,不要外键用ruby dsl格式(但是has_many之类关联设置后面最好设一下:dependent参数)。然后直接用test:units,不用事先自己建立test表结构。 |
|
返回顶楼 | |
发表时间:2006-10-10
强,完全命中.给你五星.虽然不是用db:test:clone_structure来建立test的,前面也说了,不知道怎么回事 db:test:clone_structure 因为有中文注释,而无法运行完整。所以干脆直接用用mysql直接导入了完整的sql脚本.看来这个错误是这个动作的连锁反应了.
|
|
返回顶楼 | |
发表时间:2006-10-10
上次的中文注释我是把schema改成sql模式然后改dump出来的db/development_structure.sql,按utf8格式保存,再load回去,好像没什么问题。
|
|
返回顶楼 | |