Chuyển đến nội dung
Trang chủ IntoSQL

Chuyển cơ sở dữ liệu SQLite sang SQLite cũ hơn hoặc mới hơn

Thả tệp cơ sở dữ liệu SQLite (.db, .sqlite, .sqlite3) hoặc SQL mà .dump của sqlite3 viết, và tải xuống tập lệnh nạp được trên SQLite 3.31 trở lên. Mỗi cột giữ kiểu và collation đã khai báo, STRICT được bỏ để phiên bản cũ chấp nhận các bảng, và mọi thay đổi được liệt kê trong báo cáo.

Tệp của bạn
sqlshop_2024_sqlite.sqlTệp mẫu, 3,4 kB
Cơ sở dữ liệu của bạn

Đã chuyển đổi 18 hàng, không có bản sửa, không hàng nào bị từ chối

Hiển thị

Các bảng trong shop_2024_sqlite.sqlBản dump SQLite · do sqlite3 ghi · utf-8

  • customers8 hàng
    7 cột
    idINTEGER not null
    nameTEXT not null
    emailTEXT not null
    countryTEXT not null
    is_activeINTEGER not null
    signed_upDATE
    created_atDATETIME not null
  • orders10 hàng
    9 cột
    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
    receiptBLOB

Không được chuyển đổi

  • Khung nhìn order_totals
  • Trình kích hoạt orders_shipped

Mỗi cơ sở dữ liệu viết các đối tượng này bằng ngôn ngữ riêng. Hãy viết lại chúng cho SQLite.

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

CREATE TABLE customers (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    email TEXT COLLATE NOCASE NOT NULL,
    country TEXT DEFAULT 'US' NOT NULL,
    is_active INTEGER DEFAULT 1 NOT NULL,
    signed_up DATE,
    created_at DATETIME DEFAULT (datetime('now', 'localtime')) NOT NULL,
    CONSTRAINT customers_is_active_check CHECK (is_active IN (0, 1)),
    CONSTRAINT customers_check1 CHECK (length(country) = 2)
);

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,
    receipt BLOB,
    CONSTRAINT orders_check1 CHECK (status IN ('pending', 'paid', 'shipped', 'cancelled')),
    CONSTRAINT orders_fkey FOREIGN KEY (customer_id) REFERENCES customers (id) ON DELETE CASCADE
);

INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(1,'Ana Martínez','ana@example.com','MX',1,'2023-01-15','2023-01-15 10:24:00');
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(2,'Zoë Müller','zoe@example.de','DE',1,'2023-02-03','2023-02-03 08:11:42');
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(3,'José Peña','jose@example.es','ES',0,'2023-03-21','2023-03-21 19:05:17');
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(4,'李雷','lilei@example.cn','CN',1,'2023-05-09','2023-05-09 02:40:00');
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(5,'Noah O''Brien','noah@example.ie','IE',1,NULL,'2023-06-30 14:00:00');
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(6,'Amélie Laurent','amelie@example.fr','FR',1,'2024-01-02','2024-01-02 09:30:00');
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(7,'Ravi Patel','ravi@example.in','IN',0,'2024-02-29','2024-02-29 23:59:59');
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(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, receipt) VALUES
(1,1,'shipped',129.9,3,'2024-03-01 10:00:00','2024-03-02 16:30:00',NULL,NULL);
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, receipt) VALUES
(2,2,'paid',54,1,'2024-03-02 11:15:00',NULL,'Gift wrap 🎁',NULL);
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, receipt) VALUES
(3,1,'cancelled',12.5,1,'2024-03-03 09:45:00',NULL,'Customer changed their mind',NULL);
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, receipt) VALUES
(4,4,'shipped',980,12,'2024-03-05 02:10:00','2024-03-07 08:00:00','请小心轻放',X'25504446');
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, receipt) VALUES
(5,5,'pending',45.75,2,'2024-03-08 17:20:00',NULL,'Leave at the door;
ring twice',NULL);
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, receipt) VALUES
(6,6,'shipped',310.4,5,'2024-03-10 13:00:00','2024-03-11 09:00:00','Fragile: "glass"',NULL);
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, receipt) VALUES
(7,8,'paid',76.2,2,'2024-03-11 18:45:00',NULL,NULL,NULL);
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, receipt) VALUES
(8,2,'paid',19.99,1,'2024-03-12 08:00:00',NULL,'Paid at the counter',NULL);
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, receipt) VALUES
(9,3,'shipped',64,2,'2024-03-14 15:30:00',NULL,'Shipping date never recorded',NULL);
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, receipt) VALUES
(10,7,'paid',1499,1,'2024-03-15 21:05:00',NULL,'C:\Users\ravi\invoice.pdf',NULL);

-- Indexes, triggers and counters, after the rows so each index builds once.
CREATE UNIQUE INDEX customers_email 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, 8) WHERE name = 'customers';
INSERT INTO sqlite_sequence (name, seq) SELECT 'customers', 8 WHERE NOT EXISTS (SELECT 1 FROM sqlite_sequence WHERE name = 'customers');
UPDATE sqlite_sequence SET seq = max(seq, 10) WHERE name = 'orders';
INSERT INTO sqlite_sequence (name, seq) SELECT 'orders', 10 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;

Bản sửa

Không có gì cần sửa.

Cần xem lại

  • 2 khung nhìn, trình kích hoạt, thủ tục hoặc sự kiện không được chuyển đổi; báo cáo liệt kê từng mục. Hãy tạo lại chúng thủ công trong SQLite.

Tệp được chuyển đổi ngay trên máy tính này và không bao giờ được tải lên.

Mẫu khác:

Những gì thay đổi giữa tệp và tập lệnh

Mỗi hàng là một quy tắc trình chuyển đổi áp dụng, kèm dòng báo cáo được ghi khi quy tắc thay đổi dữ liệu của bạn.

  • declared types (any text: VARCHAR(255), DATETIME, BOOLEAN, JSON or none)

    kiểu mà mọi giá trị trong cột đều vừa

    Cùng các kiểu đã khai báo, nên giá trị được nạp như khi được lưu.

  • BOOLEAN, BOOL

    INTEGER 0 hoặc 1 kèm CHECK

    Khi mọi giá trị là 0 hoặc 1; cột còn chứa giá trị khác thì giữ chúng dưới dạng số hoặc văn bản.

  • TEXT, VARCHAR(n), CHAR(n), CLOB

    kiểu đã khai báo, giữ nguyên trạng

    SQLite không bao giờ áp đặt độ dài; độ dài đã khai báo chỉ được giữ khi mọi giá trị đều vừa.

  • DECIMAL(p,s), NUMERIC

    kiểu chính xác khi mọi giá trị đều vừa, nếu không thì double

    SQLite lưu chúng dưới dạng số nguyên hoặc double; độ chính xác đã khai báo chỉ được giữ khi các giá trị vừa.

  • BLOB, and columns holding bytes

    BLOB

    Byte vẫn là byte; văn bản và số trong cùng cột được giữ dưới dạng byte của chúng.

  • DATE, DATETIME, TIMESTAMP holding ISO 8601 text

    DATE, DATETIME dưới dạng văn bản ISO 8601

    Khi mọi giá trị là ngày hoặc ngày và giờ; số epoch và văn bản khác giữ nguyên giá trị.

  • JSON holding JSON text

    TEXT

    Khi mọi giá trị là đối tượng hoặc mảng JSON.

  • Infinity in REAL columns

    9e999, vô cực riêng của SQLite

    SQLite ghi vô cực dưới dạng một hằng số tràn, được nạp lại thành vô cực.

  • INTEGER PRIMARY KEY, AUTOINCREMENT

    INTEGER PRIMARY KEY, giữ AUTOINCREMENT

    Chỉ cột được khai báo đúng là INTEGER PRIMARY KEY mới là rowid; mỗi hàng giữ id của nó, và bộ đếm bắt đầu sau id lớn nhất từng được cấp.

  • COLLATE NOCASE

    COLLATE NOCASE

    Cùng collation.

  • generated columns

    cột tính toán, STORED hoặc VIRTUAL như trong nguồn

    SQLite tính chúng theo cùng cách.

  • generated columns with functions IntoSQL doesn't write, and the || operator

    một cột thường

    Công thức không viết được để lại một cột thường và một dòng trong báo cáo; bản dump không có giá trị cho cột tính toán.

    Dòng báo cáo: generated_not_translated

  • defaults with functions IntoSQL doesn't write (strftime, randomblob)

    không có giá trị mặc định

    Giá trị mặc định không viết được sẽ bị bỏ và được báo cáo; CURRENT_TIMESTAMP và datetime('now') vẫn được viết.

    Dòng báo cáo: default_not_translated

  • CHECK constraints

    được chuyển đổi

    Cùng các ràng buộc kiểm tra, được kiểm tra khi từng hàng được nạp.

  • CHECK constraints with functions IntoSQL doesn't write

    không được tạo

    Ràng buộc kiểm tra không viết được sẽ bị bỏ và được báo cáo.

    Dòng báo cáo: check_skipped

  • partial and expression indexes

    không được tạo

    IntoSQL ghi chỉ mục trên toàn bộ cột; hãy tạo lại các chỉ mục khác sau khi nạp.

    Dòng báo cáo: index_skipped

  • foreign keys (unenforced unless PRAGMA foreign_keys=ON)

    cùng các khóa ngoại, được liệt kê bởi PRAGMA foreign_key_check

    SQLite chỉ kiểm tra khóa ngoại khi được yêu cầu, nên hàng không có hàng cha khá phổ biến: chúng vẫn được nạp, và khóa ở trạng thái chưa kiểm tra kèm cảnh báo thay vì dừng quá trình nạp.

  • foreign keys to tables the dump doesn't create

    không được tạo

    Khóa không thể tham chiếu tới bảng không tồn tại.

    Dòng báo cáo: foreign_key_skipped

  • primary keys holding NULL, and NOT NULL columns with values that become NULL

    bỏ NOT NULL

    SQLite cho phép khóa chính không phải rowid chứa NULL; cột không thể là NOT NULL ở đích, nếu không quá trình nạp sẽ dừng.

    Dòng báo cáo: not_null_relaxed

  • views, triggers and virtual tables (FTS, R*Tree)

    được liệt kê trong báo cáo

    Mã của chúng viết bằng ngôn ngữ riêng của SQLite, và bảng ảo cần các mô-đun của SQLite; chúng được liệt kê để bạn tạo lại. Các bảng nội bộ của chúng không được sao chép.

    Dòng báo cáo: not_converted_objects

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

    kiểu suy ra từ giá trị

    Bản dump chỉ có dữ liệu thì chỉ có các hàng, nên kiểu được suy ra từ giá trị và các cột được đánh số.

    Dòng báo cáo: no_schema

  • expressions in INSERT values other than the text functions dumps write

    NULL

    unistr(), replace(), char() và || được tính như cách shell ghi chúng; các biểu thức khác không tính được nếu không có cơ sở dữ liệu.

    Dòng báo cáo: expression_value

  • NUL characters in text

    được giữ

    Shell sqlite3 và Python cắt văn bản tại ký tự NUL khi dump, nên chỉ phần đứng trước nó có trong bản dump.

  • text that isn't valid UTF-8

    byte lỗi thành ký tự thay thế

    Bản dump ghi văn bản như vậy dưới dạng byte thô; tập lệnh là UTF-8.

    Dòng báo cáo: invalid_utf8_replaced

  • text decoded twice (ñ)

    sao chép nguyên trạng

    Bản dump chứa đúng các ký tự này, nên chúng được sao chép; báo cáo chỉ ra chúng.

    Dòng báo cáo: mojibake_suspected

Trong tệpTrong tập lệnhDòng báo cáo
declared types (any text: VARCHAR(255), DATETIME, BOOLEAN, JSON or none)kiểu mà mọi giá trị trong cột đều vừaCùng các kiểu đã khai báo, nên giá trị được nạp như khi được lưu.
BOOLEAN, BOOLINTEGER 0 hoặc 1 kèm CHECKKhi mọi giá trị là 0 hoặc 1; cột còn chứa giá trị khác thì giữ chúng dưới dạng số hoặc văn bản.
TEXT, VARCHAR(n), CHAR(n), CLOBkiểu đã khai báo, giữ nguyên trạngSQLite không bao giờ áp đặt độ dài; độ dài đã khai báo chỉ được giữ khi mọi giá trị đều vừa.
DECIMAL(p,s), NUMERICkiểu chính xác khi mọi giá trị đều vừa, nếu không thì doubleSQLite lưu chúng dưới dạng số nguyên hoặc double; độ chính xác đã khai báo chỉ được giữ khi các giá trị vừa.
BLOB, and columns holding bytesBLOBByte vẫn là byte; văn bản và số trong cùng cột được giữ dưới dạng byte của chúng.
DATE, DATETIME, TIMESTAMP holding ISO 8601 textDATE, DATETIME dưới dạng văn bản ISO 8601Khi mọi giá trị là ngày hoặc ngày và giờ; số epoch và văn bản khác giữ nguyên giá trị.
JSON holding JSON textTEXTKhi mọi giá trị là đối tượng hoặc mảng JSON.
Infinity in REAL columns9e999, vô cực riêng của SQLiteSQLite ghi vô cực dưới dạng một hằng số tràn, được nạp lại thành vô cực.
INTEGER PRIMARY KEY, AUTOINCREMENTINTEGER PRIMARY KEY, giữ AUTOINCREMENTChỉ cột được khai báo đúng là INTEGER PRIMARY KEY mới là rowid; mỗi hàng giữ id của nó, và bộ đếm bắt đầu sau id lớn nhất từng được cấp.
COLLATE NOCASECOLLATE NOCASECùng collation.
generated columnscột tính toán, STORED hoặc VIRTUAL như trong nguồnSQLite tính chúng theo cùng cách.
generated columns with functions IntoSQL doesn't write, and the || operatormột cột thườngCông thức không viết được để lại một cột thường và một dòng trong báo cáo; bản dump không có giá trị cho cột tính toán.generated_not_translated
defaults with functions IntoSQL doesn't write (strftime, randomblob)không có giá trị mặc địnhGiá trị mặc định không viết được sẽ bị bỏ và được báo cáo; CURRENT_TIMESTAMP và datetime('now') vẫn được viết.default_not_translated
CHECK constraintsđược chuyển đổiCùng các ràng buộc kiểm tra, được kiểm tra khi từng hàng được nạp.
CHECK constraints with functions IntoSQL doesn't writekhông được tạoRàng buộc kiểm tra không viết được sẽ bị bỏ và được báo cáo.check_skipped
partial and expression indexeskhông được tạoIntoSQL ghi chỉ mục trên toàn bộ cột; hãy tạo lại các chỉ mục khác sau khi nạp.index_skipped
foreign keys (unenforced unless PRAGMA foreign_keys=ON)cùng các khóa ngoại, được liệt kê bởi PRAGMA foreign_key_checkSQLite chỉ kiểm tra khóa ngoại khi được yêu cầu, nên hàng không có hàng cha khá phổ biến: chúng vẫn được nạp, và khóa ở trạng thái chưa kiểm tra kèm cảnh báo thay vì dừng quá trình nạp.
foreign keys to tables the dump doesn't createkhông được tạoKhóa không thể tham chiếu tới bảng không tồn tại.foreign_key_skipped
primary keys holding NULL, and NOT NULL columns with values that become NULLbỏ NOT NULLSQLite cho phép khóa chính không phải rowid chứa NULL; cột không thể là NOT NULL ở đích, nếu không quá trình nạp sẽ dừng.not_null_relaxed
views, triggers and virtual tables (FTS, R*Tree)được liệt kê trong báo cáoMã của chúng viết bằng ngôn ngữ riêng của SQLite, và bảng ảo cần các mô-đun của SQLite; chúng được liệt kê để bạn tạo lại. Các bảng nội bộ của chúng không được sao chép.not_converted_objects
dumps without CREATE TABLE (--data-only)kiểu suy ra từ giá trịBản dump chỉ có dữ liệu thì chỉ có các hàng, nên kiểu được suy ra từ giá trị và các cột được đánh số.no_schema
expressions in INSERT values other than the text functions dumps writeNULLunistr(), replace(), char() và || được tính như cách shell ghi chúng; các biểu thức khác không tính được nếu không có cơ sở dữ liệu.expression_value
NUL characters in textđược giữShell sqlite3 và Python cắt văn bản tại ký tự NUL khi dump, nên chỉ phần đứng trước nó có trong bản dump.
text that isn't valid UTF-8byte lỗi thành ký tự thay thếBản dump ghi văn bản như vậy dưới dạng byte thô; tập lệnh là UTF-8.invalid_utf8_replaced
text decoded twice (ñ)sao chép nguyên trạngBản dump chứa đúng các ký tự này, nên chúng được sao chép; báo cáo chỉ ra chúng.mojibake_suspected

Nạp tập lệnh vào SQLite

Tập lệnh tạo bảng, sao chép các hàng, rồi thêm khóa, chỉ mục và khóa ngoại, nên nạp nhanh và dừng ở lỗi đầu tiên.

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

Khóa ngoại được khai báo trong từng bảng và các hàng được nạp khi tắt kiểm tra khóa ngoại. Sau đó tập lệnh liệt kê mọi hàng trỏ tới hàng không tồn tại, thay vì thất bại giữa chừng.

Với bản dump lớn, hãy nạp vào một tệp mới trên ổ đĩa cục bộ. Tập lệnh nạp mọi thứ trong một giao dịch với đồng bộ đĩa tắt, nên chạy ở tốc độ của ổ đĩa, và lần nạp dừng giữa chừng không để lại bảng dở dang.

Dòng lệnh nạp tệp thẳng vào cơ sở dữ liệu SQLite, không cần tạo tập lệnh. Hoàn toàn miễn phí.

Tạo bản dump SQLite để có kết quả tốt nhất

Trình chuyển đổi đọc những gì bản dump chứa. Các tùy chọn sau giữ lại nhiều dữ liệu hơn trong đó:

  • Chính tệp cơ sở dữ liệu được chuyển đổi nguyên trạng, đọc từng trang trong trình duyệt của bạn. Hãy đóng ứng dụng đang ghi vào tệp trước, để không thay đổi nào bị bỏ lại trong tệp -wal của nó.
  • sqlite3 app.db .dump > app.sql ghi cùng cơ sở dữ liệu đó dưới dạng SQL, cũng chuyển đổi được, dạng .sql hoặc .sql.gz.
  • DB Browser for SQLite ghi đoạn SQL đó qua File, Export, Database to SQL file, và iterdump() của Python cũng vậy.

Những gì không được chuyển đổi

View, trigger, thủ tục, hàm và các đối tượng khác viết bằng ngôn ngữ riêng của SQLite được liệt kê theo tên trong báo cáo, không bao giờ bị bỏ âm thầm, để bạn kiểm tra từng cái với phiên bản SQLite bạn nạp vào trước khi tạo lại.

Câu hỏi về chuyển SQLite giữa các phiên bản

Chưa có câu trả lời ở đây? Hãy viết cho chúng tôi từ trang liên hệ, sẽ có người trả lời. Trang liên hệ

Bản dump của tôi có bị tải lên không?

Không. Trình chuyển đổi chạy trong trình duyệt và đọc bản dump từ ổ đĩa theo từng phần, nên nó không bao giờ rời khỏi máy tính của bạn. Ứng dụng máy tính và dòng lệnh cũng chuyển đổi ngay trên máy tính của bạn.

Bản dump có thể lớn đến đâu?

Trình chuyển đổi không bao giờ giữ toàn bộ bản dump trong bộ nhớ: nó đọc tệp hai lần, theo từng đoạn, và ghi tập lệnh trong lúc đọc. Bản dump nhiều gigabyte vẫn chuyển đổi được trong trình duyệt, trong ứng dụng máy tính và bằng dòng lệnh.

Tôi có thể chuyển đổi trực tiếp tệp .db không?

Có. Thả tệp .db, .sqlite hoặc .sqlite3: tệp được đọc trong trình duyệt của bạn và không bao giờ được tải lên. Văn bản có ký tự NUL và mọi chữ số của một giá trị double đều đến đúng như đã lưu, điều mà .dump có thể cắt bớt.

Bản dump có thể đến từ những phiên bản SQLite nào?

Tệp cơ sở dữ liệu từ SQLite 3.0 trở lên, dạng UTF-8 hoặc UTF-16, và bản dump từ lệnh .dump của shell sqlite3 hoặc iterdump() của Python. Mọi tệp và bản dump thử nghiệm đến từ sqlite3 3.31 đến 3.54, gồm cả bảng STRICT và WITHOUT ROWID, và được so với nguồn từng ô một.

Kiểu cột được quyết định thế nào khi SQLite không áp đặt chúng?

Mỗi cột giữ kiểu đã khai báo, COLLATE NOCASE và RTRIM cũng vậy. STRICT được bỏ đi, nên tập lệnh nạp được trên mọi phiên bản từ 3.31.

INTEGER PRIMARY KEY và AUTOINCREMENT có được giữ không?

Có. INTEGER PRIMARY KEY và AUTOINCREMENT giữ nguyên, và sqlite_sequence tiếp tục từ chỗ bản dump dừng lại.

Còn khung nhìn và trình kích hoạt thì sao?

Chúng được liệt kê theo tên trong báo cáo và không được chuyển đổi, để bạn tạo lại sau khi đã nạp các bảng.

Tập lệnh nạp được trên những phiên bản SQLite nào?

SQLite 3.31 trở lên. Mọi tệp và bản dump thử nghiệm đều nạp được trên 3.31 và 3.54, và dừng ở lỗi đầu tiên nếu có sự cố.