What have you found for these years?

2009-01-06

不熟 SQL 的下場又一

就是做了這件事:

Pet.all(:limit => 10, :offset => 5).destroy!

然後所有的資料就都被刪掉啦... 因為生出來的 SQL 是:

DELETE FROM "pets"

根本完全看不到 LIMIT 也看不到 OFFSET... 另一方面,
我也希望 LIMIT 可以省略,不然只好 LIMIT 100000000...
但 SQL 好像也不允許省略?

會想這樣做的原因,是希望保留相同條件的資料,至多 n 份。
如果 DELETE 可以用 OFFSET, 那就 OFFSET n 即可,
問題是居然不行!!!囧,害我誤砍一堆資料......
幸好不是 production data, 只是長年來的測試資料... 沒了 :s

為此想說希望 DM 不要忽略 LIMIT/OFFSET, 寫 patch 只要幾分鐘,
但寫 test 就搞死人了... sam/dm-core 的 test 太混亂,不寫了,
只是他的 mock 我看半天才把他修好。這種測試法我個人覺得真的很爛。

而 dkubb/dm-core 的 spec 則漂亮乾淨太多了,雖然數量有點恐怖...

Finished in 306.702122 seconds

10242 examples, 0 failures, 3322 pending

這還是關掉 PostgreSQL 和 MySQL 的結果咧。打開的話大概需要三倍時間,
在我可憐的 macbook 上可能要跑 900 秒吧... sam/dm-core 的 test 是太少,
但 dkubb/dm-core 的 test 也未免太多了吧 @@

而且沒試出跑 single test 的方法,每次都要跑全部,真的很累...
值得高興的是,dkubb/dm-core 的 test 不用修,因為沒有奇怪的 mock,
還有這麼多 test 中沒有一個用到 destroy! with LIMIT/OFFSET,
希望這 patch 或是之類的結果可以加進去... 這樣至少會噴出錯誤,
而不是整個就這樣給我砍掉...

相關 code 放在 gist 上:
http://gist.github.com/43742
因為 lighthouse 真的不會用,貼出去的排版都是一團糟。

rspec 的問題寫在另外一篇:rspec bug???
http://blogger.godfat.org/2009/01/rspec-bug.html



查詢途中看到這個:
Re: Deleting, skip the first n records
http://lists.mysql.com/mysql/202339

呃,是個方法。於是要先取出目標時間,然後再根據此做比較。
變得比較複雜些...

def compact! n = 3
last = user.photoships.first( :friend_id => friend_id,
:order => [:created_at.desc],
:offset => n )

return unless last
last = last.created_at

# offset won't work on delete!!!!
user.photoships( :friend_id => friend_id,
:created_at.lte => last ).destroy!
end

2 retries:

Plumm said...

> 不熟 SQL 的下場又一
好像和 SQL 無關??

godfat 真常 said...

有關啊,DELETE 不支援 LIMIT/OFFSET...
知道的話就不會做這種事了

Post a Comment

All texts are licensed under CC Attribution 3.0