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.
Đã chuyển đổi 18 hàng, không có bản sửa, không hàng nào bị từ chối
Các bảng trong shop_2024_sqlite.sqlBản dump SQLite · do sqlite3 ghi · utf-8
customers8 hàng
7 cột id INTEGER not null name TEXT not null email TEXT not null country TEXT not null is_active INTEGER not null signed_up DATE created_at DATETIME not null orders10 hàng
9 cột id INTEGER not null customer_id INTEGER not null status TEXT not null total DECIMAL(10,2) not null items INTEGER not null ordered_at DATETIME not null shipped_at DATETIME note TEXT receipt BLOB
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ệp | Trong tập lệnh | Dò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, BOOL | INTEGER 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), CLOB | kiể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), NUMERIC | kiể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 bytes | BLOBByte 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 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 text | TEXTKhi 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 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, AUTOINCREMENT | INTEGER 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 NOCASE | COLLATE NOCASECùng collation. | |
| generated columns | cộ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 || operator | mộ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 write | khô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 indexes | khô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 create | khô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 NULL | bỏ 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 write | NULLunistr(), 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-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. | 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.sqlKhó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ố.