将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中有布尔值,那么你可以转换1
和0
和1::boolean
和0::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中提到的所有模式/数据转换,但它做我所需要的。; 希望这对其他人来说是一个很好的起点。
续集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