2010-04-16 124 views
10

我創建了一個使用elixir/sqlalchemy存儲數據的python應用程序。該軟件的第二個版本要求更新以前版本中創建的任何文件以添加/刪除表格和列。用sqlalchemy和elixir更新sqlite數據庫模式

我的問題是:我該如何做到這一點?我知道sqlalchemy-migrate,但我必須說我覺得它很混亂。它沒有提到現有數據會發生什麼。此外,sqlite有reduced ALTER TABLE support,那麼如果我嘗試刪除列,那麼遷移會怎麼樣?有沒有其他方法可以使用遷移?

回答

7

你在說什麼是一個衆所周知和相當複雜的問題。它被稱爲數據庫遷移。每個優秀的項目都有一些政策來描述如何應用數據庫模式和數據突變來從一個產品版本推進到另一個產品版本。

許多框架(如Django或Ruby on Rails)都有內置或可用作插件的遷移系統。您的SQLAlchemy案例有幾種選擇:

  1. 請勿使用任何系統。只需用手寫一個/tmp/migrate.sql,寫下ALTER/DROP/CREATE語句,交叉手指並將其應用到您的SQLite基礎上。這通常是一個壞主意,因爲它很容易出錯,但是選擇取決於你。缺少全功能ALTER TABLE語句可以通過創建具有所需屬性和臨時名稱的新列,將所有數據從原始列複製到該列,刪除原始列並將新列重命名爲原始名稱來解決。表級可以使用相同的技術。
  2. 使用一些第三方移植系統,如liquibase。 Liquibase很酷,設計精良,功能強大,除了一個缺點。這真的是越野車。我嘗試了SQLite(對於SQLAlchemy是的,但實際上並不重要),它沒有做一些非常基本的事情。我搜索了一個問題,發現他們是已知的錯誤。
  3. 使用您提到的SQLAlchemy-migrate。它不像它受到靈感的ROR遷移那麼強大,它既沒有liquibase那麼強大,但它的工作原理。 SQLite限制可以用相同的方式解決。

而且您已經詢問SQLAlchemy-migrate如果嘗試刪除列時會執行什麼操作。那麼,它將刪除一列,並刪除其中的任何數據。表中的其他列將保持不變。

0

什麼讓你在sqlalchemy-migrate中困惑?它有--preview_sql和--preview_py選項來預覽它將要做的事情。一般情況下,對於任何可能的情況都無法進行正確的遷移,但您可以修改生成的遷移腳本以滿足您的需求。通過嘗試獲得答案很容易。

5

最近替代sqlalchemy-migrate的是alembic,由SQLAlchemy自己編寫。雖然後者(「同一作者」)看起來像是一個強有力的論點,但是它的缺點可能是它不支持SQLite的表變更,即它沒有SQLite缺少的ALTER支持的內置變通方法。 (有人可能會認爲這超出了範圍,很可能通過專門的python包或SQLite擴展來解決。)