如何使用数据迁移更新sqlite3模式



我可能有一个特殊的数据迁移问题:

  1. 我有一个已存在并已填充的SQLite3数据库
  2. 我确实收到了一个(希望是兼容的)数据库的新模式

Result应该是一个新的数据库,根据新的模式构建,包含尽可能多的旧数据库内容。

考虑到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或默认字段(不会失败)。

任何其他实现同样结果的方式(不需要知道具体修改了什么)都同样受欢迎。

为了能够在表中插入/导入列较少的转储,您可以为新添加的列提供默认值,或者只需将它们设置为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语句与新列一起工作,必须提供列名。

最新更新