2016-06-11 60 views
0

我有一個奇特的可能數據遷移問題:如何更新與數據遷移sqlite3的模式

  1. 我有現成的並填充sqlite3的數據庫。
  2. 我確實收到了一個(希望兼容)數據庫的新模式。

結果應該是一個新數據庫,根據新模式構建,儘可能包含舊數據庫內容。

兩個sqlite3的ALTER語句中給定的侷限性和我們的工作流程是安全的假設:

  • 正常情況下,將新列添加到表的末尾。
  • 添加的列(字段)將具有默認值或可以保留NULL。
  • 很少會添加一些表格。
  • 很少有某些表或列可能被刪除。
  • 將不會發生表/列重命名。
  • 不會發生列轉換。

注意:如果新的模式是不與舊的兼容(即:任何上述假設不成立),它接受失敗得很慘。

我想這個腳本(舊的數據庫是data.sql3和新模式是data.schema):

mkdir tmp 
cd tmp 

#compute old DB schema 
sqlite3 ../data.sql3 .schema >old_s 

#purge new schema for any initialization... 
grep -v ^INSERT ../data.schema >data.schema 
#... create a dew, empty DB... 
sqlite3 new.sql3 <data.schema 
#... and compute a standard schema 
#(this is done to avoid typing differences) 
sqlite3 new.sql3 .schema >new_s 

#iff the schemas are different 
if ! diff -q old_s new_s 
then 
    #save old DB 
    mv ../data.sql3 . 
    #dump contents 
    sqlite3 data.sql3 .dump >old_d 
    #expunge all statements needed to recreate DB/Tables 
    #new_d contains only INSERT statements 
    grep -v -f old_s old_d >new_d 
    #add old DB content to new DB 
    sqlite3 new.sql3 <new_d 
    #move new DB in place 
    mv new.sql3 ../data.sql3 
fi 
cd .. 

本工程以檢測更改,但未能重新填充新的數據庫,因爲.dump不包含列名稱,並且插入失敗(缺失值)。

我正在尋找一些方法來迫使sqlite3 DB .dump輸出包含所有字段名(通常它依賴於位置),或者,它那是不可能的INSERT陳述,某種方式告訴sqlite3 DB <new_d考慮任何不確定的領域爲null或默認(沒有失敗)。

同樣歡迎任何其他方式來達到相同的結果(不需要知道什麼,確切地說,已被修改)。

+0

我會說不,沒有一種簡單或自動的方法來解決這個問題。對於每個數據庫版本,您必須設置遷移腳本,並將查詢的行從舊數據調整到新模式。 – Murphy

+0

@Murphy:我不太清楚。我只關心數據庫遷移。使用它的軟件已經使用完整的列名稱(即:沒有「select * from」或位置查詢)。另外「位置」問題無論如何是因爲SQLite3只允許在最後添加列。我需要的是能夠導入字段少於所需字段的轉儲,「簡單地」根據需要添加空字段而無需保存。 – ZioByte

+0

[帶列名的SQLite導出]的可能重複(http://stackoverflow.com/questions/4199850/sqlite-export-with-column-names) – Murphy

回答

0

爲了能夠在列表中插入/導入包含較少列的轉儲,您可以爲新的附加列提供默認值,或者只需將它們設置爲NULL即可。約束條款是CREATE TABLEALTER TABLE相同:

http://www.sqlite.org/syntax/column-constraint.html

-- newColumn is set to a default value if not provided with INSERT 
alter table myTable 
add column newColumn INTEGER NOT NULL default 0; 

-- newColumn may be NULL, which is the default if not provided with INSERT 
alter table myTable 
add column newColumn INTEGER; 

-- It is also valid to combine NULL and DEFAULT constraints 
alter table myTable 
add column newColumn INTEGER default 0; 

注意,爲了使INSERT語句來新列工作,它必須提供列名。

+0

讓我改述一下,然後:我如何強制SQLite3轉換爲「.dump」,包括列名?我的問題是我想轉儲一個數據庫較少的列,並導入到一個不同的一個有一些添加列,設置多餘的列爲空/默認由任何人「增強」的數據庫指定。我可用的是:舊數據庫和新數據庫的模式。我可以安全地假設,由於添加了表(可以將它們留空)或者由於添加了列(要按模式中定義的缺省值/空值填充),所以這兩個模式只有*不同。 – ZioByte

+0

@ZioByte你最好重新說明你的問題,並提供必要的細節,以便我們看到你真正的問題是:http://stackoverflow.com/help/how-to-ask – Murphy

+0

謝謝,完成;我希望這更清楚。 – ZioByte