Saya telah melakukan pengembangan menggunakan database SQLITE dengan produksi di POSTGRESQL. Saya baru saja memperbarui database lokal saya dengan sejumlah besar data dan perlu mentransfer tabel tertentu ke database produksi.
Berdasarkan berjalan sqlite database .dump > /the/path/to/sqlite-dumpfile.sql
, SQLITE mengeluarkan tabel dump dalam format berikut:
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;
Bagaimana cara mengonversi yang di atas menjadi file dump yang kompatibel dengan POSTGRESQL yang dapat saya impor ke server produksi saya?
Jawaban:
Anda harus dapat memasukkan file dump itu langsung ke
psql
:Jika Anda ingin
id
kolom menjadi "auto increment" maka ubah jenisnya dari "int" menjadi "serial" di baris pembuatan tabel. PostgreSQL kemudian akan melampirkan urutan ke kolom itu sehingga INSERT dengan id NULL akan secara otomatis diberikan nilai berikutnya yang tersedia. PostgreSQL juga tidak akan mengenaliAUTOINCREMENT
perintah, jadi ini perlu dihapus.Anda juga ingin memeriksa
datetime
kolom dalam skema SQLite dan mengubahnya menjaditimestamp
untuk PostgreSQL. (Terima kasih kepada Clay karena telah menunjukkan hal ini.)Jika Anda memiliki boolean di SQLite, Anda dapat mengonversi
1
dan0
menjadi1::boolean
dan0::boolean
(masing-masing) atau Anda dapat mengubah kolom boolean menjadi integer di bagian skema dump dan kemudian memperbaikinya secara manual di dalam PostgreSQL setelah impor.Jika Anda memiliki BLOB di SQLite Anda, maka Anda harus menyesuaikan skema yang akan digunakan
bytea
. Anda mungkin perlu menggabungkan beberapadecode
panggilan juga . Menulis mesin fotokopi quick'n'dirty dalam bahasa favorit Anda mungkin lebih mudah daripada merusak SQL jika Anda memiliki banyak BLOB yang harus ditangani.Seperti biasa, jika Anda memiliki kunci asing maka Anda mungkin ingin melihat ke dalam
set constraints all deferred
untuk menghindari memasukkan masalah pengurutan, menempatkan perintah di dalam pasangan BEGIN / COMMIT.Terima kasih kepada Nicolas Riley untuk boolean, blob, dan catatan kendala.
Jika Anda memiliki
`
kode Anda, seperti yang dibuat oleh beberapa klien SQLite3, Anda harus menghapusnya.PostGRESQL juga tidak mengenali
unsigned
kolom, jadi Anda mungkin ingin menghapusnya atau menambahkan batasan yang dibuat khusus seperti ini:CREATE TABLE tablename ( ... unsigned_column_name integer CHECK (unsigned_column_name > 0) );
Meskipun SQLite secara default
''
menetapkan nilai null menjadi , PostgreSQL mengharuskannya disetel sebagaiNULL
.Sintaks dalam file dump SQLite tampaknya sebagian besar kompatibel dengan PostgreSQL sehingga Anda dapat menambal beberapa hal dan memasukkannya ke dalamnya
psql
. Mengimpor tumpukan besar data melalui SQL INSERT mungkin membutuhkan waktu beberapa saat tetapi itu akan berhasil.sumber
datetime
kolom sqlite , Anda harus mengubahnya menjaditimestamp
untuk postgres.BLOB
menjadiBYTEA
( stackoverflow.com/questions/3103242 ), mengubah 0/1 untukBOOLEAN
kolom menjadi '0' / '1', dan menunda batasan (DEFERRABLE
/SET CONSTRAINTS ALL DEFERRED
).pgloader
Saya menemukan posting ini ketika mencari cara untuk mengubah dump SQLite menjadi PostgreSQL. Meskipun postingan ini memiliki jawaban yang diterima (dan jawaban yang bagus di +1 itu), saya pikir menambahkan ini penting.
Saya mulai mencari solusi di sini dan menyadari bahwa saya sedang mencari metode yang lebih otomatis. Saya mencari dokumen wiki:
https://wiki.postgresql.org/wiki/Converting_from_other_Databases_to_PostgreSQL
dan ditemukan
pgloader
. Aplikasi yang cukup keren dan relatif mudah digunakan. Anda dapat mengonversi file SQLite datar menjadi database PostgreSQL yang dapat digunakan. Saya menginstal dari*.deb
dan membuatcommand
file seperti ini di direktori pengujian: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';
seperti negara bagian dokumen . Saya kemudian membuat
testdb
dengancreatedb
:createdb testdb
Saya menjalankan
pgloader
perintah seperti ini:pgloader command
lalu terhubung ke database baru:
psql testdb
Setelah beberapa pertanyaan untuk memeriksa data, tampaknya itu bekerja dengan cukup baik. Saya tahu jika saya mencoba menjalankan salah satu skrip ini atau melakukan konversi bertahap yang disebutkan di sini, saya akan menghabiskan lebih banyak waktu.
Untuk membuktikan konsepnya, saya membuang ini
testdb
dan mengimpornya ke dalam lingkungan pengembangan di server produksi dan data ditransfer dengan baik.sumber
Saya menulis script untuk melakukan
sqlite3
untukpostgres
migrasi. Itu tidak menangani semua skema / terjemahan data yang disebutkan di https://stackoverflow.com/a/4581921/1303625 , tetapi itu melakukan apa yang saya perlu lakukan. Semoga menjadi titik awal yang baik bagi orang lain.https://gist.github.com/2253099
sumber
The sekuel permata (perpustakaan Ruby) menawarkan data menyalin seluruh database yang berbeda: http://sequel.jeremyevans.net/rdoc/files/doc/bin_sequel_rdoc.html#label-Copy+Databases
Pertama instal Ruby, lalu instal gem dengan menjalankan
gem install sequel
.Dalam kasus sqlite, akan seperti ini:
sequel -C sqlite://db/production.sqlite3 postgres://user@localhost/db
sumber
pgloader
.Anda dapat menggunakan satu liner, berikut adalah contoh dengan bantuan perintah 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
sumber
sed -e 's/DATETIME/TIMESTAMP/g'
sed -e 's/TINYINT(1)/SMALLINT/g'
- dan untuk perbandingan semua tipe data, lihat stackoverflow.com/questions/1942586/…' | sed -e '
dengan;
:)Saya telah mencoba mengedit / regexping sqlite dump sehingga PostgreSQL menerimanya, itu membosankan dan rawan kesalahan.
Apa yang saya dapatkan untuk bekerja sangat cepat:
Pertama buat ulang skema di PostgreSQL tanpa data apa pun, baik mengedit dump atau jika Anda menggunakan ORM, Anda mungkin beruntung dan itu berbicara ke kedua ujung belakang (sqlalchemy, peewee, ...).
Kemudian migrasikan data menggunakan panda. Misalkan Anda memiliki tabel dengan bidang bool (yaitu 0/1 di sqlite, tetapi harus t / f di PostgreSQL)
def int_to_strbool(df, column): df = df.replace({column: 0}, 'f') df = df.replace({column: 1}, 't') return df #def other_transform(df, column): #... conn = sqlite3.connect(db) df = pd.read_sql(f'select * from {table_name}', conn) df = int_to_strbool(df, bool_column_name) #df = other_transform(df, other_column_name) df.to_csv(table_name + '.csv'), sep=',', header=False, index=False)
Ini bekerja seperti pesona, mudah untuk menulis, membaca, dan men-debug setiap fungsi, tidak seperti ekspresi reguler (bagi saya).
Sekarang Anda dapat mencoba memuat csv yang dihasilkan dengan PostgreSQL (bahkan secara grafis dengan alat admin), dengan satu-satunya peringatan bahwa Anda harus memuat tabel dengan kunci asing setelah Anda memuat tabel dengan kunci sumber yang sesuai. Saya tidak memiliki kasus ketergantungan melingkar, saya kira Anda dapat menangguhkan sementara pemeriksaan kunci jika itu masalahnya.
sumber
pgloader bekerja dengan sangat baik dalam mengonversi database di sqlite ke postgresql.
Berikut adalah contoh untuk mengonversi sqlitedb lokal ke db PostgreSQL jarak jauh:
pgloader sqlite.db postgresql: // nama pengguna : kata sandi @ nama host / nama db
sumber
KABOOM! Control stack exhausted (no more space for function call frames).