将SQLITE SQL转储文件转换为POSTGRESQL

我一直在开发使用SQLITE数据库在POSTGRESQL生产。 我刚刚更新了大量数据的本地数据库,并需要将特定的表传输到生产数据库。

根据运行sqlite database .dump > /the/path/to/sqlite-dumpfile.sql以下列格式输出表转储:

 BEGIN TRANSACTION; CREATE TABLE "courses_school" ("id" integer PRIMARY KEY, "department_count" integer NOT NULL DEFAULT 0, "the_id" integer UNIQUE, "school_name" varchar(150), "slug" varchar(50)); INSERT INTO "courses_school" VALUES(1,168,213,'TEST Name A',NULL); INSERT INTO "courses_school" VALUES(2,0,656,'TEST Name B',NULL); .... COMMIT; 

如何将上述内容转换为可导入到生产服务器的POSTGRESQL兼容转储文件?

您应该能够将该转储文件直接送入psql

 /path/to/psql -d database -U username -W < /the/path/to/sqlite-dumpfile.sql 

如果你想id列“自动增量”,那么在表格创build行中将其types从“int”更改为“serial”。 PostgreSQL然后将一个序列附加到该列,以便具有NULL ID的INSERT将被自动分配下一个可用的值。 PostgreSQL也不会识别AUTOINCREMENT命令,所以需要删除这些命令。

您还需要检查SQLite架构中的datetime列,并将其更改为PostgreSQL的timestamp (感谢Clay指出了这一点)。

如果你在你的SQLite中有布尔值,那么你可以转换101::boolean0::boolean (分别),或者你可以改变布尔列到转储的架构部分的整数,然后修复它们导入后在PostgreSQL里面手动。

如果您的SQLite中有BLOB,那么您将需要调整架构以使用bytea 。 您可能还需要混合一些decode调用 。 用你最喜欢的语言写一个快速复制的复制器,如果你需要处理很多的BLOB,可能比重新编译SQL容易一些。

像往常一样,如果你有外键,那么你可能会想要查看set constraints all deferred以避免插入顺序问题,将命令放在BEGIN / COMMIT对内。

感谢Nicolas Riley提供的布尔,blob和约束条件。

如果你的代码有一些SQLite3客户端生成的代码,你需要删除它们。

PostGRESQL也不能识别unsigned列,你可能想要删除它,或者添加一个自定义的约束,例如:

 CREATE TABLE tablename ( ... unsigned_column_name integer CHECK (unsigned_column_name > 0) ); 

虽然SQLite默认空值为'' ,PostgreSQL要求他们被设置为NULL

SQLite转储文件中的语法似乎与PostgreSQL大部分兼容,所以你可以修补一些东西并将其提供给psql 。 通过SQL INSERT导入大量的数据可能需要一段时间,但它会工作。

pgloader

当我search一种将SQLite转储转换为PostgreSQL的方式时,我遇到了这个post。 尽pipe这篇文章有一个可以接受的答案(在+1版里也是一个很好的答案),但我认为增加这一点很重要。

我开始研究这里的解决scheme,并意识到我正在寻找一种更加自动化的方法。 我查了一下wiki文档:

https://wiki.postgresql.org/wiki/Converting_from_other_Databases_to_PostgreSQL

并发现了pgloader 。 非常酷的应用程序,它相对容易使用。 您可以将平面SQLite文件转换为可用的PostgreSQL数据库。 我从*.deb安装,并在testing目录中创build了一个像这样的command文件:

 load database from 'db.sqlite3' into postgresql:///testdb with include drop, create tables, create indexes, reset sequences set work_mem to '16MB', maintenance_work_mem to '512 MB'; 

像文档状态。 然后我用createdb创build了一个testdb

createdb testdb

我运行这样的pgloader命令:

pgloader command

然后连接到新的数据库:

psql testdb

经过一些查询来检查数据,它似乎工作得很好。 我知道如果我试图运行这些脚本之一,或者做这里提到的逐步转换,我会花更多的时间。

为了certificate这个概念,我把这个testdb放到了生产服务器上的开发环境中,并且很好地传输了数据。

我写了一个脚本来执行sqlite3 postgres迁移。 它不处理在https://stackoverflow.com/a/4581921/1303625中提到的所有模式/数据转换,但它做我所需要的。; 希望这对其他人来说是一个很好的起点。

https://gist.github.com/2253099

续集gem (一个Ruby库)提供跨不同数据库的数据复制: http : //sequel.jeremyevans.net/rdoc/files/doc/bin_sequel_rdoc.html#label-Copy+Databases

在sqlite的情况下,它会是这样的: sequel -C sqlite://db/production.sqlite3 postgres://user@localhost/db

您可以使用一个class轮,这里是一个例子与sed命令的帮助:

 sqlite3 mjsqlite.db .dump | sed -e 's/INTEGER PRIMARY KEY AUTOINCREMENT/SERIAL PRIMARY KEY/' | sed -e 's/PRAGMA foreign_keys=OFF;//' | sed -e 's/unsigned big int/BIGINT/g' | sed -e 's/UNSIGNED BIG INT/BIGINT/g' | sed -e 's/BIG INT/BIGINT/g' | sed -e 's/UNSIGNED INT(10)/BIGINT/' | sed -e 's/BOOLEAN/SMALLINT/g' | sed -e 's/boolean/SMALLINT/g' | sed -e 's/UNSIGNED BIG INT/INTEGER/g' | sed -e 's/INT(3)/INT2/g' | sed -e 's/DATETIME/TIMESTAMP/g' | psql mypqdb mypguser