论坛首页 编程语言技术论坛

rake test_units删除表的问题

浏览 5754 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2006-10-07  
在运行test_units后,test数据库的表会被全部删除,然后再重建。
不过这个过程有些问题,它是删除一个表,然后马上就重建。
这样的话,如果被删除的表,还有一个父表存在,就不能被删除。重建过程也会失败。
test_units就运行失败了。失败就失败吧,可是test_units的结果都没有显示出来,郁闷.

能不能把这个过程修改下,改成先删除全部的表,然后再重建所有表。这样的过程就不会受各种FK影响了。

   发表时间:2006-10-08  
用rake db:test:purge可以强制删掉所有表。Rails对外键不是太友好,特别是fixture。
0 请登录后投票
   发表时间:2006-10-08  
cookoo 写道
用rake db:test:purge可以强制删掉所有表。Rails对外键不是太友好,特别是fixture。

强制删除表的问题还好。关键是rake test_units的结果看不到了.想修正下rake test_units最后的那个删除和重建过程,有没有办法?至少让我看下test_units的结果。

如果rake改不了这个,只好自己写脚本了.一个一个的运行ruby ...test.rb,也是够麻烦的
0 请登录后投票
   发表时间: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
0 请登录后投票
   发表时间:2006-10-09  
cookoo 写道

对mysql来说它会先执行db:test:purge删除整个数据库(不是一个一个删表)再重建


执行test_units时,察看了下mysql的sql语句执行过程,很明显的,是先drop table 然后再create table,create index.
每一个表都是这样的执行过程。
然后有张表 先drop,create时,提示表已经存在.也就是前面的drop 根本没有成功.但是没有报错,到了create时才出错.

0 请登录后投票
   发表时间: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表结构。
0 请登录后投票
   发表时间:2006-10-10  
强,完全命中.给你五星.虽然不是用db:test:clone_structure来建立test的,前面也说了,不知道怎么回事 db:test:clone_structure 因为有中文注释,而无法运行完整。所以干脆直接用用mysql直接导入了完整的sql脚本.看来这个错误是这个动作的连锁反应了.
0 请登录后投票
   发表时间:2006-10-10  
上次的中文注释我是把schema改成sql模式然后改dump出来的db/development_structure.sql,按utf8格式保存,再load回去,好像没什么问题。
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics