2010-03-16 22 views
6

我正在使用Phingdbdeploy taskmanage my database schema。這工作正常,只要在我的增量文件的查詢中沒有錯誤。獲取Phing的dbdeploy任務以自動回滾delta錯誤

但是,如果出現錯誤,dbdeploy將只運行增量文件直到帶有錯誤的查詢,然後中止。這使我感到沮喪,因爲我必須手動回滾changelog表中的條目。如果我不這樣做,dbdeploy會認爲遷移在後續嘗試中是成功的,因此任何重試都不會執行任何操作。

所以問題是,是否有任何方法可以獲取dbdeploy使用事務,或者您可以建議任何其他方式在發生錯誤時自動進行phing回滾

注意:我並不精通Phing,所以如果這涉及到編寫自定義任務,任何示例代碼或帶有進一步信息的url都將受到高度讚賞。謝謝

+0

我認爲在當前狀態phings dbdeploy不如其專注於DB-版本只項目。 請參閱http://stackoverflow.com/questions/3324571/is-there-a-php-equivalent-of-rails-遷移例如 – 2011-08-02 10:52:57

回答

3

(如果你還在那裏......)關於數據庫轉儲任務的phing,使用數據庫的轉儲實用程序並創建一個phing任務。我使用Postgres的主要是和這個在我phing的build.xml:

<target name="db-dump" depends=""> 
    <php expression="date('Ymd-Hi')" returnProperty="phing.dump.ts"/> 
    <exec command="pg_dump -h ${db.host} -U ${db.user} -O ${db.name} | gzip > ${db.dumppath}/${db.name}-${phing.dump.ts}.gz" /> 
</target> 
-1

執行此操作的「正確」方法是在模式更改之前進行備份,然後在發生錯誤時進行回滾。

你不說你使用了什麼數據庫 - 但它會想知道如果所有的模式更改將在事務中被支持。 Mos大腿端SQL數據庫(oracle,db2,sql server)在所有情況下都不會這麼做,原因很簡單。 Transacitonal模式變化是非常困難的,而且真的是資源密集型的。

+0

謝謝。使用MySQL,但我正在考慮使用它來管理Oracle 10g中的一些視圖。任何想法如何用Phing做備份呢? – Gordon 2010-03-16 11:41:48

+0

沒有。不應該在那裏完成。在配置/軟件更改之前進行備份是管理員的工作。 – TomTom 2010-03-16 12:09:08

+4

嗯,那有點擊敗自動部署工具像phing的目的,不是嗎? – Gordon 2010-03-16 12:22:33

1

爲什麼不寫一系列的撤銷增量並添加一個運行在另一個任務失敗的phing任務?

+0

謝謝。我確實有撤消增量。但是我怎麼能自動運行它們?另一個phing任務如何知道還能跑多遠? – Gordon 2010-03-16 17:35:42

+0

在知道多遠回來你可以設置一個屬性的起點。至於自動運行,我不知道你可以自動執行它,但是設置一個檢查數據庫版本控制表的任務並基於該任務運行撤消操作。 你可能想看看xinc有成功和失敗的通告,並且能夠根據成功或失敗運行一些代碼邏輯。 – 2010-03-17 00:23:15

1

你真的應該看看capistrano。 TomTom:您在這裏丟失了一些東西:模式更改之前的備份當然必須完成 - 但如果插入的新數據如何處理,您認爲一切正常?我不說,這個問題有一個好的工具,但問題存在於現實生活中。

+0

感謝您的建議。如果可能的話,我想留在PHP生態系統中。 – Gordon 2010-06-28 22:40:17

3

解決您的問題的最簡單的方法是使用默認的事務中運行SQL腳本pdoexec任務。當錯誤發生時,數據庫引擎會自動回滾所做的更改(在更改日誌表甚至包括那些 - 數據庫將以前的狀態)

例子:

<pdosqlexec 
    url="pgsql:host=${db.host} 
    dbname=${db.name}" 
    userid="${db.user}" 
    password="${db.pass}" 
    src="${build.dbdeploy.deployfile}" 
/> 
+0

非常好!這工作完美。 – Clint 2012-02-09 19:23:39

+0

這是否適用於DDL更改語句?至少在MySql中,這些不能被回滾。 – Gordon 2014-04-28 16:07:36

3

我知道,這是非常古老的線程,但也許它會被其他人充分使用。 您可以使用try-> catch語句來實現該解決方案。 我的例子:

<trycatch> 
    <try> 
     <exec 
      command="${progs.mysql} -h${db.live.host} -u${db.live.user} -p${db.live.password} ${db.live.name} &lt; ${db.live.output}/${build.dbdeploy.deployfile}" 
      dir="${project.basedir}" 
      checkreturn="true" /> 
      <echo>Live database was upgraded successfully</echo> 
    </try>  
    <catch> 
      <echo>Errors in upgrading database</echo> 
      <exec 
      command="${progs.mysql} -h${db.live.host} -u${db.live.user} -p${db.live.password} ${db.live.name} &lt; ${db.live.output}/${build.dbdeploy.undofile}" 
      dir="${project.basedir}" 
      checkreturn="true" /> 
    </catch> 
    </trycatch>