저는 POSTGRESQL에서 프로덕션과 함께 SQLITE 데이터베이스를 사용하여 개발을 해왔습니다. 방대한 양의 데이터로 로컬 데이터베이스를 업데이트했으며 특정 테이블을 프로덕션 데이터베이스로 전송해야합니다.
실행을 기반으로 sqlite database .dump > /the/path/to/sqlite-dumpfile.sql
SQLITE는 다음 형식으로 테이블 덤프를 출력합니다.
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
“자동 증가”에 열을 후 테이블 생성 줄에 “시리얼”에서 “INT”에서 유형을 변경합니다. 그런 다음 PostgreSQL은 해당 열에 시퀀스를 연결하여 NULL ID가있는 INSERT에 다음 사용 가능한 값을 자동으로 할당합니다. PostgreSQL은 AUTOINCREMENT
명령을 인식하지 못 하므로 제거해야합니다.
또한 datetime
SQLite 스키마에서 열 을 확인 timestamp
하고 PostgreSQL 용으로 변경하고 싶을 것 입니다. ( 이 점을 지적 해 주신 Clay 에게 감사드립니다 .)
당신이 당신의 SQLite는의 논리 값이 있다면 당신은 변환 할 수 1
와 0
로 1::boolean
와 0::boolean
(각각)하거나 덤프의 스키마 섹션에서 정수로 부울 열을 변경 한 다음 가져 오기 후 PostgreSQL의 내부에 손으로 그들을 해결할 수 있습니다.
SQLite에 BLOB가있는 경우를 사용하도록 스키마를 조정하고 싶을 것 bytea
입니다. 일부 decode
통화도 믹스해야 할 것입니다 . 하지만 처리해야 할 BLOB가 많으면 좋아하는 언어로 빠르고 더러운 복사기를 작성하는 것이 SQL을 조작하는 것보다 쉬울 수 있습니다.
평소처럼 외래 키가있는 경우 set constraints all deferred
삽입 순서 문제를 방지하기 위해 BEGIN / COMMIT 쌍 안에 명령을 배치하는 것이 좋습니다.
부울, 블롭 및 제약 사항 메모에 대해 Nicolas Riley 에게 감사드립니다 .
`
일부 SQLite3 클라이언트에 의해 생성 된 코드 가있는 경우 이를 제거해야합니다.
PostGRESQL은 또한 unsigned
열을 인식하지 않으므로이를 삭제하거나 다음과 같은 사용자 지정 제약 조건을 추가 할 수 있습니다.
CREATE TABLE tablename (
...
unsigned_column_name integer CHECK (unsigned_column_name > 0)
);
SQLite는 기본적으로 null 값 ''
을로 설정하지만 PostgreSQL에서는이를로 설정해야합니다 NULL
.
SQLite 덤프 파일의 구문은 대부분 PostgreSQL과 호환되므로 몇 가지를 패치하고 psql
. SQL INSERT를 통해 많은 양의 데이터를 가져 오는 데는 시간이 걸릴 수 있지만 작동합니다.
답변
pgloader
SQLite 덤프를 PostgreSQL로 변환하는 방법을 찾을 때이 게시물을 보았습니다. 이 게시물에 허용 된 답변 (그리고 해당 +1에서 좋은 답변)이 있지만 추가하는 것이 중요하다고 생각합니다.
여기서 솔루션을 찾기 시작했고 더 자동화 된 방법을 찾고 있다는 것을 깨달았습니다. 위키 문서를 찾았습니다.
https://wiki.postgresql.org/wiki/Converting_from_other_Databases_to_PostgreSQL
그리고 발견 pgloader
. 매우 멋진 응용 프로그램이며 비교적 사용하기 쉽습니다. 플랫 SQLite 파일을 사용 가능한 PostgreSQL 데이터베이스로 변환 할 수 있습니다. 에서 설치 하고 테스트 디렉토리에 다음과 같은 파일을 *.deb
만들었습니다 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';
문서 상태 처럼 . 그런 다음 다음 testdb
과 createdb
같이 만들었습니다 .
createdb testdb
다음 pgloader
과 같은 명령을 실행했습니다 .
pgloader command
그런 다음 새 데이터베이스에 연결됩니다.
psql testdb
데이터를 확인하기 위해 몇 가지 쿼리를 수행 한 후 꽤 잘 작동하는 것으로 보입니다. 이 스크립트 중 하나를 실행하거나 여기에 언급 된 단계적 변환을 시도했다면 훨씬 더 많은 시간을 보냈을 것입니다.
개념을 증명하기 위해 나는 이것을 버리고 testdb
프로덕션 서버의 개발 환경으로 가져오고 데이터를 멋지게 전송했습니다.
답변
내가 할 수있는 스크립트 작성 sqlite3
에 postgres
마이그레이션. https://stackoverflow.com/a/4581921/1303625에 언급 된 모든 스키마 / 데이터 번역을 처리하지는 않지만 필요한 작업을 수행합니다. 다른 사람들에게 좋은 출발점이되기를 바랍니다.
답변
속편 보석 (루비 라이브러리) 다른 데이터베이스에서 복사 된 데이터를 제공
http://sequel.jeremyevans.net/rdoc/files/doc/bin_sequel_rdoc.html#label-Copy+Databases
먼저 Ruby를 설치 한 다음 gem install sequel
.
sqlite의 경우 다음과 같습니다.
sequel -C sqlite://db/production.sqlite3 postgres://user@localhost/db
답변
하나의 라이너를 사용할 수 있습니다. 다음은 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
답변
나는 sqlite 덤프를 편집 / 정규화하여 PostgreSQL이 그것을 받아들이고 지루하고 오류가 발생하기 쉽습니다.
정말 빨리 일하게 된 것 :
먼저 데이터없이 PostgreSQL에서 스키마를 다시 생성합니다. 덤프를 편집하거나 ORM을 사용하는 경우 운이 좋을 수 있으며 두 백엔드 (sqlalchemy, peewee, …)와 통신합니다.
그런 다음 Pandas를 사용하여 데이터를 마이그레이션합니다. bool 필드가있는 테이블이 있다고 가정합니다 (sqlite에서는 0/1이지만 PostgreSQL에서는 t / f 여야 함).
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)
이것은 매력처럼 작동하며 정규 표현식과 달리 각 함수를 작성하고 읽고 디버그하기 쉽습니다.
이제 PostgreSQL을 사용하여 결과 csv를로드 할 수 있습니다 (관리 도구를 사용하여 그래픽으로도). 순환 종속성의 경우가 없었습니다. 그렇다면 일시적으로 키 확인을 중단 할 수 있습니다.
답변
pgloader 작업은 sqlite의 데이터베이스를 postgresql로 변환하는 데 놀라운 일입니다.
다음은 로컬 sqlitedb를 원격 PostgreSQL db로 변환하는 예입니다.
pgloader sqlite.db postgresql : // 사용자 이름 : 암호 @ 호스트 이름 / dbname
