2012-03-06 41 views
2

我們有一小段代碼使用SQLAlchemy將源數據庫(在我們的例子中爲MSSQL)複製到目標數據庫(在我們的例子中是SQLite在內存中)。作爲這個複製的一部分,我們從源複製表信息到目標:創建表時修改DEFAULT子句

for table in source: 
    table.tometadata(metadata_target) 
    # some more stuff (hack: could alter table here) 
metadata_target.create_all() 

在複製表中,DEFAULT條款得到逐字複製。例如。 SQLite中複製的列可能是這樣的:

CREATE TABLE "TableName" (
    -- ... 
    "TimeStamp" DATETIME DEFAULT (GETUTCDATE()) NOT NULL, 
    -- ... 
) 

這不起作用,因爲GETUTCDATE()不是SQLite中的功能。

我要尋找一個勾入SQLAlchemy的DDL編譯器(我猜),我可以修改或抑制DEFAULT部分取決於價值和方言(S)的產生(例如用DATE('now')或降更換GETUTCDATE()NEWID()完全)的默認子句)。

我看過this part of the documentation(我們用它來處理交叉編譯期間的某些類型),但我不知道如何使用它來處理DEFAULT子句。我甚至不確定它是否是正確的工具。我可以破解這個(通過改變SQLAlchemy「創建」後的表),但我更喜歡更通用的解決方案。

回答

1

你也可以爲你的SQLite連接實現GETUTCDATE函數。

+0

+1我在某些情況下已經這樣做了,但'GETUTCDATE'在SQLite中有或多或少的直接等價物,所以我不喜歡使用自定義函數。我目前替換這個「手動」,但這是一個黑客。 – stephan 2012-03-08 10:20:48

1

還有另一種解決方案,但是搞砸了,數據庫變得無法使用。它會工作,但不建議。 SQLite將該模式保存在名爲sqlite_master的表中。您無法正常寫入此表,但使用pragma writable_schema=on您可以寫入。做出你想要的任何改變,然後關掉雜注。最後,爲了確保不會因爲在SQLite下更改模式而導致問題,請關閉數據庫並重新打開它。

+0

現在就是我所說的黑客!值得+1;)我目前的解決方案基本上修改了對'table.tometadata(metadata_target)'和'metadata_target.create_all()'的調用之間的模式。這是我能想出的最佳解決方案。我希望SQLAlchemy能讓我直接用鉤子編譯DDL(就像在其他情況下使用'@compiles'裝飾器一樣),但這似乎並非如此,所以我必須忍受這個黑客。 – stephan 2012-03-13 07:19:20