Package: pgsqlite
pgsqliteLoad SQLite3 databases into PostgresSQL.Usage:usage: pgsqlite.py [-h] -f SQLITE_FILENAME -p POSTGRES_CONNECT_URL [-d DEBUG] [--drop_tables DROP_TABLES] [--drop_everything DROP_EVERYTHING] [--drop_tables_after_import DROP_TABLES_AFTER_IMPORT]

optional arguments:
  -h, --help            show this help message and exit
  -f SQLITE_FILENAME, --sqlite_filename SQLITE_FILENAME
                        sqlite database to import
  -p POSTGRES_CONNECT_URL, --postgres_connect_url POSTGRES_CONNECT_URL
                        Postgres URL for the database to import into
  -d DEBUG, --debug DEBUG
                        Set log level to DEBUG
  --drop_tables DROP_TABLES
                        Prior to import, drop tables in the target database that have the same name as tables in the source database
  --drop_everything DROP_EVERYTHING
                        Prior to import, drop everything (tables, views, triggers, etc, etc) in the target database before the import
  --drop_tables_after_import DROP_TABLES_AFTER_IMPORT
                        Drop all tables in the target database after import; useful for testingExamples:Import into the bit.io databaseadam/AMEND, with DEBUG-level logging.python pgsqlite.py  -f ../example_dbs/Chinook_Sqlite.sqlite -p postgresql://adam:<password>@db.bit.io/adam/AMEND --debug trueImport into the bit.io databaseadam/AMEND, dropping all tables in the target database that match tables in the source database:python pgsqlite.py  -f ../example_dbs/Chinook_Sqlite.sqlite -p postgresql://adam:<password>@db.bit.io/adam/AMEND --drop_tables trueMost of the drop options are used for testing - be aware they are destructive operations!TestingThere's a set of open-source databases in theexample_dbs/directory, and./import_examples.shscript that will test importing of all those databases.
You'll need to setPOSTGRES_CREDS_STRINGto your connect string before hand,
and also be aware this script will drop everything in the target database, so be careful!How This WorksFor more details, read:https://innerjoin.bit.io/introducing-pgsqlite-a-pure-python-module-to-import-sqlite-databases-into-postgres-bf3940cfa19fSQLite is far more forgiving a database then Postgree. Look at thisCREATE TABLE:CREATE TABLE Customer_Ownership(
  customer_id INTEGER NOT NULL,
  vin INTEGER NOT NULL,
  purchase_date DATE NOT NULL,
  purchase_price INTEGER NOT NULL,
  warantee_expire_date DATE,
  dealer_id INTEGER NOT NULL,
  FOREIGN KEY (customer_id) REFERENCES Customers(customer_id),
  FOREIGN KEY (vin) REFERENCES Car_Vins(vin),
  FOREIGN KEY (dealer_id) REFERENCES Dealers(dealer_id)
  PRIMARY KEY (customer_id, vin)
);This is totally valid in SQLite and is missing a comma on the second to last line. In fact, this is what
you'd get back from.schemain the sqlite command line tool.For pgsqlite, this means we cannot use the excellentsqlglotmodule to transpile the schema creation SQL
as the module is too strict for some sqlite databases.
We need the (also excellent)sqlite-utilsmodule.sqlite-utilsgives us python objects that represent
the database entities, which lets us then create Postgres-valid SQL to create these entities.We use psycopg (version 3) to gain access to the very fastCOPYprotocol. We filter that incoming data
to make sure we have nulls set correctly, and to do any transforms on the literal values that are required
(like the BOOLEAN example in Known Issues, below).Known IssuesMost of the issues are around constraints that involve SQL that requires literals. For example, aBOOLEANcolumn may have aCHECKconstraint
likeIN (1, 0)which is valid in SQLite but not in Postgres (in SQLite the integers1and0are true/false, but not in Postgres). To fix
this we'd need to parse the SQL, identify the literals and which columns they map to, then "fix" the literal's type. This also impacts views & triggers.TODOSUnit testsAppend modeAsync loading of dataWith async, a status property that tells us, eg "x of y rows loaded in table z"