runsisi's

technical notes

postgresql 数据导入到 sqlite

2019-03-04 runsisi#fe#db

以 example 数据库实例为例。

首先把 postgresql 中的 example 实例的表结构和数据导出来

sudo -u postgres pg_dump -p 5433 --schema-only example > schema.sql
sudo -u postgres pg_dump -p 5433 --data-only --inserts example > data.sql

使用 vim 打开 data.sql,首先执行如下命令进行全局删除或替换

:g/^SET/d
:g/SELECT pg_catalog.setval/d

:%s/\<true\>/1/g
:%s/\<false\>/0/g

然后在第一行增加 BEGIN; 在最后一行增加 END;

BEGIN;
...
END;

由于 sqlite 对于表操作的支持和 postgresql 不一致,如不支持权限控制,索引不支持具体的索引算法(只支持 btree),PRIMARY KEY 等各种 CONSTRAINT 不支持通过 ALTER TABLE 命令实现,因此对 schema.sql 的修改较多,最好打开一个sqlite 数据库边修改边进行实际导入测试。

先可以做一些基本的清理工作:

:g/^SET/d
:g/^CREATE EXTENSION/d
:g/^COMMENT ON/d

:g/^REVOKE/d
:g/^GRANT/d
:g/^ALTER TABLE.\+OWNER TO.\+/d
:g/^ALTER SEQUENCE.\+OWNED BY.\+/d

:%s/USING btree //

:g/^ALTER TABLE.\+SET DEFAULT nextval.\+/d

# convert SEQUENCE、PRIMARY KEY、FOREIGN KEY、UNIQUE to CRATE TABLE
# :%s/^CREATE SEQUENCE\_.\{-};//

剩下的如 primary key, autoincrement 等需要手工一一修改,某些 INDEX 命令也需要修改。

注意:sqlite 的 AUTOINCREMENT 属性只可以作用在 PRIMARY KEY 上,且不能作用在独立的 PRIMARY 约束上,即只能是如下所示:

CREATE TABLE account_mygraph (
    id integer NOT NULL PRIMARY KEY AUTOINCREMENT,
    profile_id integer NOT NULL,
    name character varying(64) NOT NULL,
    url text NOT NULL,
    FOREIGN KEY (profile_id) REFERENCES account_profile(id) DEFERRABLE INITIALLY DEFERRED
);

而不能是:

CREATE TABLE account_mygraph (
    id integer NOT NULL AUTOINCREMENT,
    profile_id integer NOT NULL,
    name character varying(64) NOT NULL,
    url text NOT NULL,
    PRIMARY KEY (id),
    FOREIGN KEY (profile_id) REFERENCES account_profile(id) DEFERRABLE INITIALLY DEFERRED
);

导入 schema 和 数据 到 sqlite 中

~$ sqlite3 example.db
SQLite version 3.11.0 2016-02-15 17:29:24
Enter ".help" for usage hints.
sqlite> .read schema.sql

sqlite> .read data.sql

sqlite> .schema
CREATE TABLE account_mygraph (
    id integer NOT NULL PRIMARY KEY AUTOINCREMENT,
    profile_id integer NOT NULL,
    name character varying(64) NOT NULL,
    url text NOT NULL,
    FOREIGN KEY (profile_id) REFERENCES account_profile(id) DEFERRABLE INITIALLY DEFERRED
);
...

参考资料

Convert PostgreSQL to SQLite

https://manuelvanrijn.nl/blog/2012/01/18/convert-postgresql-to-sqlite/

SQL Features That SQLite Does Not Implement

https://www.sqlite.org/omitted.html

SQLite AUTOINCREMENT : Why You Should Avoid Using It

http://www.sqlitetutorial.net/sqlite-autoincrement/