본문으로 건너뛰기
IntoSQL 홈

PostgreSQL에서 SQLite로 변환

pg_dump나 pg_dumpall로 만든 .sql 또는 .sql.gz 일반 덤프를 놓으면, 같은 테이블, 키, 인덱스, 데이터를 담은 SQLite 스크립트를 다운로드할 수 있어요. SQLite이(가) 그대로 담을 수 없는 값과 옮기지 않는 객체는 모두 보고서에 나와요.

내 파일
sqlshop_2024_postgres.sql샘플 파일, 6.2kB
내 데이터베이스

18개 행 변환, 수정 3개, 거부 없음

보기

shop_2024_postgres.sql의 테이블PostgreSQL 18.6 덤프 · pg_dump(으)로 작성됨 · utf8mb4

  • customers8개 행2
    8개 열
    idINTEGER not null
    nameTEXT not null
    emailTEXT not null
    countryVARCHAR(2) not null
    is_activeINTEGER not null
    tagsTEXT not null
    signed_upDATE
    created_atTIMESTAMP not null
  • orders10개 행1
    10개 열
    idINTEGER not null
    customer_idINTEGER not null
    statusTEXT not null
    totalDECIMAL(10,2) not null
    itemsINTEGER not null
    ordered_atDATETIME not null
    shipped_atDATETIME
    noteTEXT
    detailsTEXT
    deliveryTEXT

변환되지 않음

  • 뷰 paid_orders

데이터베이스마다 이 객체를 자체 언어로 작성해요. SQLite에 맞게 다시 작성하세요.

-- Written by IntoSQL from a PostgreSQL dump. Load it with: sqlite3 -bail <database> < <file>
PRAGMA foreign_keys = OFF;
PRAGMA synchronous = OFF;
BEGIN;

CREATE TABLE customers ( -- People who bought at least once
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    email TEXT NOT NULL,
    country VARCHAR(2) DEFAULT 'US' NOT NULL,
    is_active INTEGER DEFAULT 1 NOT NULL,
    tags TEXT NOT NULL,
    signed_up DATE,
    created_at TIMESTAMP DEFAULT (strftime('%Y-%m-%d %H:%M:%f', 'now')) NOT NULL,
    CONSTRAINT customers_is_active_check CHECK (is_active IN (0, 1))
);

CREATE TABLE orders (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    customer_id INTEGER NOT NULL,
    status TEXT DEFAULT 'pending' NOT NULL,
    total DECIMAL(10,2) NOT NULL,
    items INTEGER DEFAULT 1 NOT NULL,
    ordered_at DATETIME NOT NULL,
    shipped_at DATETIME,
    note TEXT,
    details TEXT,
    delivery TEXT,
    CONSTRAINT orders_status_check CHECK (status IN ('pending', 'paid', 'shipped', 'cancelled')),
    CONSTRAINT orders_orders_total_check CHECK (total >= (0)),
    CONSTRAINT orders_customer_id_fkey FOREIGN KEY (customer_id) REFERENCES customers (id)
);

INSERT INTO customers (id, name, email, country, is_active, tags, signed_up, created_at) VALUES
(1,'Ana Martínez','ana@example.com','MX',1,'["vip"]','2023-01-15','2023-01-15 10:24:00'),
(2,'Zoë Müller','zoe@example.de','DE',1,'[]','2023-02-03','2023-02-03 08:11:42'),
(3,'José Peña','jose@example.es','ES',0,'["wholesale","late payer"]','2023-03-21','2023-03-21 19:05:17'),
(4,'李雷','lilei@example.cn','CN',1,'[]','2023-05-09','2023-05-09 02:40:00'),
(5,'Noah O''Brien','noah@example.ie','IE',1,'[]',NULL,'2023-06-30 14:00:00'),
(6,'Amélie Laurent','amelie@example.fr','FR',1,'["vip"]','2024-01-02','2024-01-02 09:30:00'),
(7,'Ravi Patel','ravi@example.in','IN',0,'[]','2024-02-29','2024-02-29 23:59:59'),
(8,'Sofia Rossi 🌻','sofia@example.it','IT',1,'[]','2024-04-12','2024-04-12 12:12:12');
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, details, delivery) VALUES
(1,1,'shipped',129.90,3,'2024-03-01 10:00:00','2024-03-02 16:30:00',NULL,'{"gift": false}','1 day 06:30:00'),
(2,2,'paid',54.00,1,'2024-03-02 11:15:00',NULL,'Gift wrap 🎁','{"gift": true, "wrap": "red"}',NULL),
(3,1,'cancelled',12.50,1,'2024-03-03 09:45:00',NULL,'Customer changed their mind',NULL,NULL),
(4,4,'shipped',980.00,12,'2024-03-05 02:10:00','2024-03-07 08:00:00','请小心轻放','{"fragile": true}','2 days 05:50:00'),
(5,5,'pending',45.75,2,'2024-03-08 17:20:00',NULL,'Leave at the door; ring twice',NULL,NULL),
(6,6,'shipped',310.40,5,'2024-03-10 13:00:00','2024-03-11 09:00:00','Fragile: "glass"','{"fragile": true}','20:00:00'),
(7,8,'paid',76.20,2,'2024-03-11 18:45:00',NULL,NULL,NULL,NULL),
(8,2,'shipped',19.99,1,'2024-03-12 08:00:00',NULL,'Shipped date set to infinity by an old import',NULL,NULL),
(9,3,'shipped',64.00,2,'2024-03-14 15:30:00','2024-03-15 10:00:00','Two parcels','{"parcels": [1, 2]}','18:30:00'),
(10,7,'paid',1499.00,1,'2024-03-15 21:05:00',NULL,'C:\Users\ravi\invoice.pdf',NULL,NULL);

-- Indexes, triggers and counters, after the rows so each index builds once.
CREATE UNIQUE INDEX customers_customers_email_key ON customers (email);
CREATE INDEX orders_idx_orders_customer ON orders (customer_id);
CREATE INDEX orders_idx_orders_status_date ON orders (status, ordered_at);
UPDATE sqlite_sequence SET seq = max(seq, 1000) WHERE name = 'customers';
INSERT INTO sqlite_sequence (name, seq) SELECT 'customers', 1000 WHERE NOT EXISTS (SELECT 1 FROM sqlite_sequence WHERE name = 'customers');
UPDATE sqlite_sequence SET seq = max(seq, 5000) WHERE name = 'orders';
INSERT INTO sqlite_sequence (name, seq) SELECT 'orders', 5000 WHERE NOT EXISTS (SELECT 1 FROM sqlite_sequence WHERE name = 'orders');
COMMIT;

-- Rows whose foreign key finds no parent, if any: the load doesn't stop for them.
PRAGMA foreign_key_check;

수정 사항

  1. customers의 "created_at" 열에는 시간대가 있는 시점이 들어 있어요. SQLite에는 시간대를 유지하는 타입이 없어서 TIMESTAMP(으)로 UTC로 저장해요.
  2. customers의 "tags" 열은 SQLite에 없는 text[](이)라서 같은 값을 담은 TEXT(으)로 만들었어요.
  3. orders의 "delivery" 열은 SQLite에 없는 interval(이)라서 같은 값을 담은 TEXT(으)로 만들었어요.

확인 필요

  • 뷰, 트리거, 루틴, 이벤트 1개가 변환되지 않았어요. 보고서에 각각 나와 있어요. SQLite에서 직접 다시 만드세요.
  • customers의 "tags" 열 기본값을 SQLite용으로 쓸 수 없어(a value its type can't hold) 기본값 없이 만들었어요. 새 행에 필요하면 기본값을 직접 추가하세요.
  • orders의 인덱스 idx_orders_details은(는) SQLite용으로 쓸 수 없는 식을 사용해서(a gin index) 만들지 않았어요. 쿼리에 필요하면 인덱스를 직접 만드세요.
  • orders의 "shipped_at" 열에 있는 1개 값은 infinity처럼 SQLite이(가) 저장할 수 없는 날짜라서 NULL로 두었어요. SQLite은(는) 1년부터 9999년까지만 저장하고 infinity는 없어요. 이 날짜가 중요하면 원본에서 바꾸세요.

파일은 이 컴퓨터에서 변환되고 업로드되지 않아요.

다른 샘플:

PostgreSQL에서 SQLite로 바뀌는 점

각 행은 변환기가 적용하는 규칙이며, 규칙이 데이터를 바꿀 때 보고서에 쓰는 줄이 함께 나와요.

  • boolean

    CHECK가 붙은 INTEGER 0 또는 1

    SQLite에는 boolean 타입이 없어요. SQLite의 true와 false는 1과 0이에요.

  • varchar(n), char(n), text

    VARCHAR(n)과 TEXT, 길이는 강제하지 않음

    SQLite는 도구가 읽을 수 있도록 선언된 타입을 보관하지만 길이는 제한하지 않아요.

  • numeric(p,s) past 15 digits and numeric without a precision

    TEXT

    SQLite는 숫자에 유효 숫자를 약 15자리까지 담아요. 더 넓은 숫자는 모든 자릿수가 정확하도록 텍스트로 유지해요.

    보고서 줄: decimal_as_text

  • money

    NUMERIC

    SQLite에는 money 타입이 없어요. 금액은 서버 로캘이 붙인 통화 기호 없이 숫자로 유지해요.

    보고서 줄: type_replaced

  • interval

    PostgreSQL의 텍스트를 담은 TEXT

    SQLite에는 interval 타입이 없어요. 텍스트가 모든 부분을 유지해요.

    보고서 줄: type_replaced

  • arrays (integer[], text[]...)

    JSON 배열을 담은 TEXT

    SQLite에는 배열이 없어요. JSON 배열은 모든 항목과 NULL을 유지하고 SQLite의 JSON 함수로 읽을 수 있어요.

    보고서 줄: type_replaced

  • ranges, geometric types, tsvector, xml, hstore, PostGIS, composite and extension types

    PostgreSQL의 텍스트를 담은 TEXT

    SQLite에는 같은 타입이 없어서 각 값은 PostgreSQL이 쓴 텍스트를 유지해요.

    보고서 줄: type_replaced

  • json, jsonb

    TEXT

    SQLite의 JSON 함수는 텍스트에서 JSON을 읽어요.

  • timestamp

    ISO 8601 텍스트로 된 DATETIME

    SQLite는 날짜를 날짜 함수가 읽는 텍스트로 저장해요.

  • timestamp with time zone

    UTC 기준 ISO 8601 텍스트의 TIMESTAMP

    SQLite에는 오프셋을 유지하는 타입이 없어서 각 시점을 UTC로 써요. 덤프에 적힌 오프셋과 상관없이 같은 시점이에요.

    보고서 줄: moments_as_utc

  • time

    텍스트의 TIME

    SQLite는 24:00:00을 포함해 시각을 텍스트로 보관해요.

  • infinity, -infinity and BC dates

    NULL

    SQLite의 날짜 함수는 0년부터 9999년까지만 읽고 infinity는 없어요. 이 값은 NULL이 되고 보고서에 개수가 나와요.

    보고서 줄: date_out_of_range

  • NaN and Infinity in numeric, real and double precision

    NULL

    SQLite는 NaN을 NULL로 저장하고 infinity는 모든 도구에서 유지되지 않아서, 이 값은 NULL이 되고 보고서에 개수가 나와요.

    보고서 줄: invalid_value_null

  • NOT NULL columns with values that become NULL

    NOT NULL 제거

    값을 NULL로 바꿔야 했던 열은 NOT NULL을 유지할 수 없어요. 유지하면 불러오기가 멈춰요.

    보고서 줄: not_null_relaxed

  • enum types

    레이블 CHECK가 붙은 TEXT

    체크 제약이 있는 텍스트는 같은 값을 유지해요.

  • enum columns holding values outside their labels

    체크 제약 없는 TEXT

    레이블에 없는 값은 체크 제약에 걸리므로 체크 제약을 만들지 않아요.

    보고서 줄: enum_check_skipped

  • uuid, inet, cidr, macaddr

    TEXT

    SQLite에는 이런 타입이 없어요. 텍스트가 모든 값을 유지해요.

  • bytea

    BLOB

    바이트는 바이트 그대로 남아요.

  • bit(n), bit varying

    63비트까지는 비트 값의 INTEGER, 그 이상은 자릿수의 TEXT

    비트 문자열은 부호 있는 정수에 들어가는 동안 비트가 만드는 숫자로 저장해요.

  • oid, xid, cid

    음수가 아닌지 확인하는 CHECK가 붙은 INTEGER

    SQLite의 64비트 정수는 모든 값을 담아요.

  • citext and nondeterministic collations

    정확한 비교

    SQLite는 따로 지정하지 않으면 텍스트를 정확히 비교하고, NOCASE는 ASCII 문자만 대소문자를 무시해요.

    보고서 줄: case_insensitive_collation

  • serial, identity

    INTEGER PRIMARY KEY AUTOINCREMENT, 가장 큰 id 다음부터 이어짐

    SQLite는 정수 기본 키 전체에 번호를 매기고, AUTOINCREMENT는 시퀀스처럼 id가 재사용되지 않게 해요.

  • serial and identity columns that aren't the whole primary key

    카운터 없는 INTEGER

    SQLite는 기본 키 전체인 열에만 번호를 매기므로, 열은 값을 유지하고 새 행은 직접 값을 넣어야 해요.

    보고서 줄: counter_dropped

  • sequences not owned by a column

    만들지 않음

    SQLite에는 시퀀스가 없어요.

    보고서 줄: sequence_not_converted

  • generated columns

    GENERATED ALWAYS AS, 원본과 같은 STORED 또는 VIRTUAL

    SQLite 3.31 이상은 생성 열을 같은 두 가지 방식으로 계산해요.

  • generated columns with functions SQLite lacks

    값을 담은 일반 열

    SQLite용으로 쓸 수 없는 수식은 덤프의 값을 담은 일반 열로 남고 보고서에 한 줄 기록돼요.

    보고서 줄: generated_not_translated

  • defaults with functions SQLite lacks, and defaults from a sequence

    기본값 없음

    SQLite용으로 쓸 수 없는 기본값은 제외하고 보고해요.

    보고서 줄: default_not_translated

  • CHECK constraints

    변환해서 CREATE TABLE 안에 인라인으로

    SQLite는 CREATE TABLE 안에서만 체크 제약을 받아요.

  • CHECK constraints with functions SQLite lacks

    만들지 않음

    SQLite용으로 쓸 수 없는 체크 제약은 제외하고 보고해요.

    보고서 줄: check_skipped

  • CHECK ... NOT VALID

    만들지 않음

    PostgreSQL은 기존 행을 검사한 적이 없고, SQLite는 불러오는 동안 그 행을 검사할 거예요.

    보고서 줄: check_not_valid

  • gin, gist, brin and hash indexes, partial and expression indexes

    만들지 않음

    IntoSQL은 SQLite용으로 열에 대한 b-tree 인덱스를 써요. 다른 인덱스는 불러온 뒤 다시 만드세요.

    보고서 줄: index_skipped

  • foreign keys

    CREATE TABLE 안에 두고, 검사 없이 불러온 뒤 PRAGMA foreign_key_check로 나열

    SQLite는 CREATE TABLE에서만 외래 키를 받고, PRAGMA foreign_keys가 켜져 있을 때만 검사해요. 행은 검사 없이 불러오고, 스크립트 마지막에 부모 행이 없는 행을 나열해요.

  • foreign keys to tables the dump doesn't create

    만들지 않음

    키는 없는 테이블을 가리킬 수 없어요.

    보고서 줄: foreign_key_skipped

  • partitioned tables

    모든 파티션의 행을 담은 하나의 테이블

    행은 같아요.

    보고서 줄: partitions_dropped

  • schemas

    하나의 파일, 테이블 이름 앞에 스키마 이름

    SQLite 파일은 하나의 데이터베이스라서 스키마 이름으로 이름이 같은 테이블을 구분해요. public의 테이블은 이름을 유지해요.

    보고서 줄: schemas_merged

  • views, functions, procedures, triggers, rules, policies, extensions and types

    보고서에 나열

    코드가 PostgreSQL의 언어로 작성되어 있어서 직접 다시 만들 수 있도록 나열해요.

    보고서 줄: not_converted_objects

  • dumps without CREATE TABLE (--data-only)

    값으로 판단한 타입

    데이터만 있는 덤프에는 행만 있어서 타입을 값으로 판단해요.

    보고서 줄: no_schema

  • expressions in INSERT values

    NULL

    데이터베이스를 실행하지 않는 변환기는 이 식을 계산할 수 없어요.

    보고서 줄: expression_value

  • types IntoSQL doesn't know

    TEXT

    텍스트는 어떤 값이든 담아요. 불러온 뒤 타입을 바꾸세요.

    보고서 줄: unknown_type

  • text that isn't valid in its encoding

    잘못된 바이트를 대체 문자로

    SQLite 텍스트는 UTF-8이에요.

    보고서 줄: invalid_utf8_replaced

  • text decoded twice (ñ)

    그대로 복사

    덤프에 정확히 이 문자들이 있으므로 그대로 복사하고, 보고서에서 알려 줘요.

    보고서 줄: mojibake_suspected

PostgreSQL에서SQLite에서보고서 줄
booleanCHECK가 붙은 INTEGER 0 또는 1SQLite에는 boolean 타입이 없어요. SQLite의 true와 false는 1과 0이에요.
varchar(n), char(n), textVARCHAR(n)과 TEXT, 길이는 강제하지 않음SQLite는 도구가 읽을 수 있도록 선언된 타입을 보관하지만 길이는 제한하지 않아요.
numeric(p,s) past 15 digits and numeric without a precisionTEXTSQLite는 숫자에 유효 숫자를 약 15자리까지 담아요. 더 넓은 숫자는 모든 자릿수가 정확하도록 텍스트로 유지해요.decimal_as_text
moneyNUMERICSQLite에는 money 타입이 없어요. 금액은 서버 로캘이 붙인 통화 기호 없이 숫자로 유지해요.type_replaced
intervalPostgreSQL의 텍스트를 담은 TEXTSQLite에는 interval 타입이 없어요. 텍스트가 모든 부분을 유지해요.type_replaced
arrays (integer[], text[]...)JSON 배열을 담은 TEXTSQLite에는 배열이 없어요. JSON 배열은 모든 항목과 NULL을 유지하고 SQLite의 JSON 함수로 읽을 수 있어요.type_replaced
ranges, geometric types, tsvector, xml, hstore, PostGIS, composite and extension typesPostgreSQL의 텍스트를 담은 TEXTSQLite에는 같은 타입이 없어서 각 값은 PostgreSQL이 쓴 텍스트를 유지해요.type_replaced
json, jsonbTEXTSQLite의 JSON 함수는 텍스트에서 JSON을 읽어요.
timestampISO 8601 텍스트로 된 DATETIMESQLite는 날짜를 날짜 함수가 읽는 텍스트로 저장해요.
timestamp with time zoneUTC 기준 ISO 8601 텍스트의 TIMESTAMPSQLite에는 오프셋을 유지하는 타입이 없어서 각 시점을 UTC로 써요. 덤프에 적힌 오프셋과 상관없이 같은 시점이에요.moments_as_utc
time텍스트의 TIMESQLite는 24:00:00을 포함해 시각을 텍스트로 보관해요.
infinity, -infinity and BC datesNULLSQLite의 날짜 함수는 0년부터 9999년까지만 읽고 infinity는 없어요. 이 값은 NULL이 되고 보고서에 개수가 나와요.date_out_of_range
NaN and Infinity in numeric, real and double precisionNULLSQLite는 NaN을 NULL로 저장하고 infinity는 모든 도구에서 유지되지 않아서, 이 값은 NULL이 되고 보고서에 개수가 나와요.invalid_value_null
NOT NULL columns with values that become NULLNOT NULL 제거값을 NULL로 바꿔야 했던 열은 NOT NULL을 유지할 수 없어요. 유지하면 불러오기가 멈춰요.not_null_relaxed
enum types레이블 CHECK가 붙은 TEXT체크 제약이 있는 텍스트는 같은 값을 유지해요.
enum columns holding values outside their labels체크 제약 없는 TEXT레이블에 없는 값은 체크 제약에 걸리므로 체크 제약을 만들지 않아요.enum_check_skipped
uuid, inet, cidr, macaddrTEXTSQLite에는 이런 타입이 없어요. 텍스트가 모든 값을 유지해요.
byteaBLOB바이트는 바이트 그대로 남아요.
bit(n), bit varying63비트까지는 비트 값의 INTEGER, 그 이상은 자릿수의 TEXT비트 문자열은 부호 있는 정수에 들어가는 동안 비트가 만드는 숫자로 저장해요.
oid, xid, cid음수가 아닌지 확인하는 CHECK가 붙은 INTEGERSQLite의 64비트 정수는 모든 값을 담아요.
citext and nondeterministic collations정확한 비교SQLite는 따로 지정하지 않으면 텍스트를 정확히 비교하고, NOCASE는 ASCII 문자만 대소문자를 무시해요.case_insensitive_collation
serial, identityINTEGER PRIMARY KEY AUTOINCREMENT, 가장 큰 id 다음부터 이어짐SQLite는 정수 기본 키 전체에 번호를 매기고, AUTOINCREMENT는 시퀀스처럼 id가 재사용되지 않게 해요.
serial and identity columns that aren't the whole primary key카운터 없는 INTEGERSQLite는 기본 키 전체인 열에만 번호를 매기므로, 열은 값을 유지하고 새 행은 직접 값을 넣어야 해요.counter_dropped
sequences not owned by a column만들지 않음SQLite에는 시퀀스가 없어요.sequence_not_converted
generated columnsGENERATED ALWAYS AS, 원본과 같은 STORED 또는 VIRTUALSQLite 3.31 이상은 생성 열을 같은 두 가지 방식으로 계산해요.
generated columns with functions SQLite lacks값을 담은 일반 열SQLite용으로 쓸 수 없는 수식은 덤프의 값을 담은 일반 열로 남고 보고서에 한 줄 기록돼요.generated_not_translated
defaults with functions SQLite lacks, and defaults from a sequence기본값 없음SQLite용으로 쓸 수 없는 기본값은 제외하고 보고해요.default_not_translated
CHECK constraints변환해서 CREATE TABLE 안에 인라인으로SQLite는 CREATE TABLE 안에서만 체크 제약을 받아요.
CHECK constraints with functions SQLite lacks만들지 않음SQLite용으로 쓸 수 없는 체크 제약은 제외하고 보고해요.check_skipped
CHECK ... NOT VALID만들지 않음PostgreSQL은 기존 행을 검사한 적이 없고, SQLite는 불러오는 동안 그 행을 검사할 거예요.check_not_valid
gin, gist, brin and hash indexes, partial and expression indexes만들지 않음IntoSQL은 SQLite용으로 열에 대한 b-tree 인덱스를 써요. 다른 인덱스는 불러온 뒤 다시 만드세요.index_skipped
foreign keysCREATE TABLE 안에 두고, 검사 없이 불러온 뒤 PRAGMA foreign_key_check로 나열SQLite는 CREATE TABLE에서만 외래 키를 받고, PRAGMA foreign_keys가 켜져 있을 때만 검사해요. 행은 검사 없이 불러오고, 스크립트 마지막에 부모 행이 없는 행을 나열해요.
foreign keys to tables the dump doesn't create만들지 않음키는 없는 테이블을 가리킬 수 없어요.foreign_key_skipped
partitioned tables모든 파티션의 행을 담은 하나의 테이블행은 같아요.partitions_dropped
schemas하나의 파일, 테이블 이름 앞에 스키마 이름SQLite 파일은 하나의 데이터베이스라서 스키마 이름으로 이름이 같은 테이블을 구분해요. public의 테이블은 이름을 유지해요.schemas_merged
views, functions, procedures, triggers, rules, policies, extensions and types보고서에 나열코드가 PostgreSQL의 언어로 작성되어 있어서 직접 다시 만들 수 있도록 나열해요.not_converted_objects
dumps without CREATE TABLE (--data-only)값으로 판단한 타입데이터만 있는 덤프에는 행만 있어서 타입을 값으로 판단해요.no_schema
expressions in INSERT valuesNULL데이터베이스를 실행하지 않는 변환기는 이 식을 계산할 수 없어요.expression_value
types IntoSQL doesn't knowTEXT텍스트는 어떤 값이든 담아요. 불러온 뒤 타입을 바꾸세요.unknown_type
text that isn't valid in its encoding잘못된 바이트를 대체 문자로SQLite 텍스트는 UTF-8이에요.invalid_utf8_replaced
text decoded twice (ñ)그대로 복사덤프에 정확히 이 문자들이 있으므로 그대로 복사하고, 보고서에서 알려 줘요.mojibake_suspected

스크립트를 SQLite에 불러오기

스크립트는 테이블을 만들고 행을 복사한 다음 키, 인덱스, 외래 키를 추가해요. 그래서 빨리 불러오고 첫 오류에서 멈춰요.

sqlite3 -bail mydb.sqlite < postgresql.sqlite.sql

외래 키는 각 테이블 안에 선언하고, 행은 외래 키 검사를 끈 채로 불러와요. 그런 다음 스크립트는 중간에 실패하지 않고, 존재하지 않는 행을 가리키는 행을 모두 나열해요.

큰 덤프는 로컬 디스크의 새 파일로 불러오세요. 스크립트는 동기화를 끈 하나의 트랜잭션으로 모두 불러오므로 디스크 속도로 실행되고, 중간에 멈춰도 일부만 채워진 테이블이 남지 않아요.

명령줄은 파일을 SQLite 데이터베이스에 바로 불러와요. 스크립트를 따로 만들 필요가 없고 무료예요.

좋은 결과를 위한 PostgreSQL 덤프 방법

변환기는 덤프에 담긴 내용을 읽어요. 다음 옵션을 쓰면 더 많은 데이터가 덤프에 남아요:

  • pg_dump의 기본값인 --format=plain은 SQL을 써요. custom 또는 directory 아카이브(-Fc, -Fd)는 데이터베이스 서버 없이 pg_restore -f dump.sql로 SQL이 돼요.
  • --no-owner --no-privileges는 어차피 변환기가 건너뛰는 역할과 권한을 빼서 덤프가 작아져요.
  • pg_dumpall은 모든 데이터베이스를 한 파일에 덤프해요. 각 데이터베이스의 테이블 이름에 그 데이터베이스 이름이 붙어서 충돌하지 않아요.

변환되지 않는 것

뷰, 구체화된 뷰, 함수, 프로시저, 트리거, 규칙, 행 보안 정책, 확장, 타입은 PostgreSQL의 자체 언어로 작성돼요. 보고서에 이름으로 나열되고 몰래 빠지는 일은 없으므로, SQLite에 맞게 다시 작성할 수 있어요.

PostgreSQL에서 SQLite로 변환에 관한 질문

여기에 답이 없나요? 문의 페이지로 연락하시면 담당자가 답장해요. 문의 페이지

덤프가 업로드되나요?

아니요. 변환기는 브라우저에서 실행되고 디스크의 덤프를 조각조각 읽으므로, 덤프가 컴퓨터 밖으로 나가지 않아요. 데스크톱 앱과 명령줄도 컴퓨터에서 변환해요.

덤프는 얼마나 커도 되나요?

변환기는 덤프 전체를 메모리에 올리지 않아요. 파일을 범위별로 두 번 읽고, 읽는 대로 스크립트를 써요. 수 GB 덤프도 브라우저, 데스크톱 앱, 명령줄에서 변환돼요.

pg_dump -Fc 아카이브도 읽나요?

직접은 읽지 않아요. custom 아카이브는 바이너리 형식이에요. pg_restore -f dump.sql dump.backup을 실행하면 서버에 연결하지 않고 변환기가 읽는 일반 SQL로 바뀌어요. 아카이브를 받으면 변환기가 이렇게 알려 줘요.

어떤 PostgreSQL 버전의 덤프를 읽나요?

PostgreSQL 10 이상에서 pg_dump와 pg_dumpall로 만든, COPY 또는 INSERT 행이 담긴 덤프예요. 모든 테스트 덤프는 PostgreSQL 13과 18에서 만들고 원본과 셀 단위로 비교해요.

serial과 identity 값은 유지되나요?

테이블의 기본 키 전체인 serial 또는 identity 열은 INTEGER PRIMARY KEY AUTOINCREMENT가 되고, 모든 행은 id를 유지하며, 다음 id는 가장 큰 id 다음부터 이어져요. 다른 열은 카운터 없이 값을 유지하고, 보고서에 그렇게 나와요.

배열, enum 등 PostgreSQL 타입은 어떻게 되나요?

배열은 JSON 배열, boolean은 0과 1, enum은 레이블 체크 제약이 붙은 텍스트, 시간대가 있는 timestamp는 UTC 텍스트가 돼요. 넓은 numeric은 텍스트로 정확히 유지돼요. 범위, 기하 타입, 복합 타입은 PostgreSQL의 텍스트를 유지해요.

함수, 트리거, 뷰는 어떻게 되나요?

데이터베이스마다 자체 언어로 작성하므로 변환하지 않고 보고서에 이름으로 나열해요.

스크립트는 어떤 SQLite 버전에서 불러올 수 있나요?

SQLite 3.31 이상이에요. 모든 테스트 덤프를 3.31과 3.54에서 불러오며, 문제가 생기면 첫 오류에서 멈춰요.