Перейти к содержимому
Главная страница IntoSQL

Перенесите базу SQLite на более старую или новую версию SQLite

Перетащите файл базы данных SQLite (.db, .sqlite, .sqlite3) или SQL, который пишет .dump в sqlite3, и скачайте скрипт, который загружается на SQLite 3.31 и новее. Каждый столбец сохраняет объявленный тип и collation, STRICT опускается, чтобы старые версии принимали таблицы, и каждое изменение указано в отчете.

Ваш файл
sqlshop_2024_sqlite.sqlПример файла, 3,4 кБ
Ваша база данных

18 строк конвертировано, без исправлений, ни одна не отклонена

Показать

Таблицы в shop_2024_sqlite.sqlДамп SQLite · создан программой sqlite3 · utf-8

  • customers8 строк
    7 столбцов
    idINTEGER not null
    nameTEXT not null
    emailTEXT not null
    countryTEXT not null
    is_activeINTEGER not null
    signed_upDATE
    created_atDATETIME not null
  • orders10 строк
    9 столбцов
    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

Не конвертировано

  • Представление order_totals
  • Триггер orders_shipped

Каждая база данных пишет их на своем языке. Перепишите их для 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;

Исправления

Исправлять ничего не пришлось.

Требует проверки

  • Не конвертированы представления, триггеры, процедуры и события (2 объекта); отчет перечисляет каждый. Создайте их заново вручную в SQLite.

Файл конвертируется на этом компьютере и никуда не загружается.

Другие примеры:

Что меняется между файлом и скриптом

Каждая строка - это правило, которое применяет конвертер, и строка отчета, которую он пишет, когда правило что-то меняет в ваших данных.

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

    тип, в который помещается каждое значение столбца

    Те же объявленные типы, поэтому значения загружаются так, как были сохранены.

  • BOOLEAN, BOOL

    INTEGER 0 или 1 с CHECK

    Если каждое значение равно 0 или 1; столбец, где есть и другие значения, сохраняет их как числа или текст.

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

    объявленный тип, как есть

    SQLite никогда не ограничивает длину; объявленная длина сохраняется, только если в нее помещается каждое значение.

  • DECIMAL(p,s), NUMERIC

    точный тип, если в него помещается каждое значение, иначе double

    SQLite хранит их как целые числа или double; объявленная точность сохраняется, только если значения в нее помещаются.

  • BLOB, and columns holding bytes

    BLOB

    Байты остаются байтами; текст и числа в том же столбце сохраняются как их байты.

  • DATE, DATETIME, TIMESTAMP holding ISO 8601 text

    DATE, DATETIME как текст ISO 8601

    Если каждое значение - дата или дата со временем; числа epoch и другой текст сохраняют свои значения как есть.

  • JSON holding JSON text

    TEXT

    Если каждое значение - объект или массив JSON.

  • Infinity in REAL columns

    9e999, собственная бесконечность SQLite

    SQLite записывает бесконечность как переполняющий литерал, который при загрузке снова становится бесконечностью.

  • INTEGER PRIMARY KEY, AUTOINCREMENT

    INTEGER PRIMARY KEY, AUTOINCREMENT сохраняется

    Только столбец, объявленный ровно как INTEGER PRIMARY KEY, является rowid; каждая строка сохраняет свой id, а счетчик начинается после наибольшего когда-либо выданного id.

  • COLLATE NOCASE

    COLLATE NOCASE

    То же сопоставление.

  • generated columns

    генерируемые столбцы, STORED или VIRTUAL, как в источнике

    SQLite вычисляет их так же.

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

    обычный столбец

    Формула, которую нельзя записать, оставляет обычный столбец и строку в отчете; в дампе нет значений для генерируемых столбцов.

    Строка отчета: generated_not_translated

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

    без значения по умолчанию

    Значение по умолчанию, которое нельзя записать, опускается и попадает в отчет; CURRENT_TIMESTAMP и datetime('now') записываются.

    Строка отчета: default_not_translated

  • CHECK constraints

    переводится

    Те же проверки, применяемые при загрузке каждой строки.

  • CHECK constraints with functions IntoSQL doesn't write

    не создается

    Проверка, которую нельзя записать, опускается и попадает в отчет.

    Строка отчета: check_skipped

  • partial and expression indexes

    не создается

    IntoSQL создает индексы по целым столбцам; остальные создайте заново после загрузки.

    Строка отчета: index_skipped

  • foreign keys (unenforced unless PRAGMA foreign_keys=ON)

    те же внешние ключи, список через PRAGMA foreign_key_check

    SQLite проверяет внешние ключи, только если это включено, поэтому строки без родителя встречаются часто: они загружаются, а ключ остается непроверенным с предупреждением, вместо того чтобы остановить загрузку.

  • foreign keys to tables the dump doesn't create

    не создается

    Ключ не может ссылаться на таблицу, которой нет.

    Строка отчета: foreign_key_skipped

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

    NOT NULL снимается

    SQLite разрешает первичному ключу, кроме rowid, содержать NULL; в целевой базе столбец не может быть NOT NULL, иначе загрузка остановится.

    Строка отчета: not_null_relaxed

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

    перечисляются в отчете

    Их код написан на собственном языке SQLite, а виртуальным таблицам нужны модули SQLite; они перечислены, чтобы вы могли создать их заново. Их внутренние таблицы не копируются.

    Строка отчета: not_converted_objects

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

    типы определяются по значениям

    Дамп только с данными содержит лишь строки, поэтому типы берутся из значений, а столбцы нумеруются.

    Строка отчета: no_schema

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

    NULL

    unistr(), replace(), char() и || вычисляются в том виде, в каком их пишет оболочка; другие выражения нельзя вычислить без базы данных.

    Строка отчета: expression_value

  • NUL characters in text

    сохраняется

    Оболочка sqlite3 и Python обрезают текст на символе NUL при создании дампа, поэтому в дампе есть только то, что стоит перед ним.

  • text that isn't valid UTF-8

    неверные байты заменяются символом замены

    Дампы записывают такой текст как сырые байты; скрипт в UTF-8.

    Строка отчета: invalid_utf8_replaced

  • text decoded twice (ñ)

    копируется как есть

    Дамп содержит именно эти символы, поэтому они копируются; отчет на них указывает.

    Строка отчета: mojibake_suspected

В файлеВ скриптеСтрока отчета
declared types (any text: VARCHAR(255), DATETIME, BOOLEAN, JSON or none)тип, в который помещается каждое значение столбцаТе же объявленные типы, поэтому значения загружаются так, как были сохранены.
BOOLEAN, BOOLINTEGER 0 или 1 с CHECKЕсли каждое значение равно 0 или 1; столбец, где есть и другие значения, сохраняет их как числа или текст.
TEXT, VARCHAR(n), CHAR(n), CLOBобъявленный тип, как естьSQLite никогда не ограничивает длину; объявленная длина сохраняется, только если в нее помещается каждое значение.
DECIMAL(p,s), NUMERICточный тип, если в него помещается каждое значение, иначе doubleSQLite хранит их как целые числа или double; объявленная точность сохраняется, только если значения в нее помещаются.
BLOB, and columns holding bytesBLOBБайты остаются байтами; текст и числа в том же столбце сохраняются как их байты.
DATE, DATETIME, TIMESTAMP holding ISO 8601 textDATE, DATETIME как текст ISO 8601Если каждое значение - дата или дата со временем; числа epoch и другой текст сохраняют свои значения как есть.
JSON holding JSON textTEXTЕсли каждое значение - объект или массив JSON.
Infinity in REAL columns9e999, собственная бесконечность SQLiteSQLite записывает бесконечность как переполняющий литерал, который при загрузке снова становится бесконечностью.
INTEGER PRIMARY KEY, AUTOINCREMENTINTEGER PRIMARY KEY, AUTOINCREMENT сохраняетсяТолько столбец, объявленный ровно как INTEGER PRIMARY KEY, является rowid; каждая строка сохраняет свой id, а счетчик начинается после наибольшего когда-либо выданного id.
COLLATE NOCASECOLLATE NOCASEТо же сопоставление.
generated columnsгенерируемые столбцы, STORED или VIRTUAL, как в источникеSQLite вычисляет их так же.
generated columns with functions IntoSQL doesn't write, and the || operatorобычный столбецФормула, которую нельзя записать, оставляет обычный столбец и строку в отчете; в дампе нет значений для генерируемых столбцов.generated_not_translated
defaults with functions IntoSQL doesn't write (strftime, randomblob)без значения по умолчаниюЗначение по умолчанию, которое нельзя записать, опускается и попадает в отчет; CURRENT_TIMESTAMP и datetime('now') записываются.default_not_translated
CHECK constraintsпереводитсяТе же проверки, применяемые при загрузке каждой строки.
CHECK constraints with functions IntoSQL doesn't writeне создаетсяПроверка, которую нельзя записать, опускается и попадает в отчет.check_skipped
partial and expression indexesне создаетсяIntoSQL создает индексы по целым столбцам; остальные создайте заново после загрузки.index_skipped
foreign keys (unenforced unless PRAGMA foreign_keys=ON)те же внешние ключи, список через PRAGMA foreign_key_checkSQLite проверяет внешние ключи, только если это включено, поэтому строки без родителя встречаются часто: они загружаются, а ключ остается непроверенным с предупреждением, вместо того чтобы остановить загрузку.
foreign keys to tables the dump doesn't createне создаетсяКлюч не может ссылаться на таблицу, которой нет.foreign_key_skipped
primary keys holding NULL, and NOT NULL columns with values that become NULLNOT NULL снимаетсяSQLite разрешает первичному ключу, кроме rowid, содержать NULL; в целевой базе столбец не может быть NOT NULL, иначе загрузка остановится.not_null_relaxed
views, triggers and virtual tables (FTS, R*Tree)перечисляются в отчетеИх код написан на собственном языке SQLite, а виртуальным таблицам нужны модули SQLite; они перечислены, чтобы вы могли создать их заново. Их внутренние таблицы не копируются.not_converted_objects
dumps without CREATE TABLE (--data-only)типы определяются по значениямДамп только с данными содержит лишь строки, поэтому типы берутся из значений, а столбцы нумеруются.no_schema
expressions in INSERT values other than the text functions dumps writeNULLunistr(), replace(), char() и || вычисляются в том виде, в каком их пишет оболочка; другие выражения нельзя вычислить без базы данных.expression_value
NUL characters in textсохраняетсяОболочка sqlite3 и Python обрезают текст на символе NUL при создании дампа, поэтому в дампе есть только то, что стоит перед ним.
text that isn't valid UTF-8неверные байты заменяются символом заменыДампы записывают такой текст как сырые байты; скрипт в UTF-8.invalid_utf8_replaced
text decoded twice (ñ)копируется как естьДамп содержит именно эти символы, поэтому они копируются; отчет на них указывает.mojibake_suspected

Загрузите скрипт в SQLite

Скрипт создает таблицы, копирует строки, затем добавляет ключи, индексы и внешние ключи, поэтому загрузка идет быстро и останавливается на первой ошибке.

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

Внешние ключи объявляются в каждой таблице, а строки загружаются с отключенной проверкой внешних ключей. Затем скрипт перечисляет все строки, которые ссылаются на несуществующие строки, а не прерывается на полпути.

Большой дамп загружайте в новый файл на локальном диске. Скрипт загружает все в одной транзакции с отключенной синхронизацией, поэтому работает со скоростью диска, а прерванная загрузка не оставляет неполных таблиц.

Командная строка загружает файл прямо в базу SQLite, без написания скрипта. Это бесплатно.

Как создать дамп SQLite для лучшего результата

Конвертер читает то, что есть в дампе. Эти параметры сохраняют в нем больше ваших данных:

  • Сам файл базы данных конвертируется как есть и читается в браузере страница за страницей. Сначала закройте приложение, которое в него пишет, чтобы ни одно изменение не осталось в его файле -wal.
  • sqlite3 app.db .dump > app.sql записывает ту же базу данных в SQL, который тоже конвертируется, в формате .sql или .sql.gz.
  • DB Browser for SQLite пишет этот SQL через File, Export, Database to SQL file, как и iterdump() в Python.

Что не конвертируется

Представления, триггеры, процедуры, функции и другие объекты, написанные на собственном языке SQLite, перечислены в отчете по имени и никогда не удаляются молча, чтобы вы могли проверить каждый на той версии SQLite, в которую загружаете, прежде чем создать его заново.

Вопросы о переносе SQLite между версиями

Нет ответа на ваш вопрос? Напишите нам через страницу контактов, и вам ответит человек. Страница контактов

Мой дамп загружается на сервер?

Нет. Конвертер работает в вашем браузере и читает дамп с диска по частям, поэтому он никогда не покидает ваш компьютер. Приложение для компьютера и командная строка тоже конвертируют на вашем компьютере.

Насколько большим может быть дамп?

Конвертер никогда не держит весь дамп в памяти: он читает файл дважды, по диапазонам, и пишет скрипт по ходу чтения. Дампы в несколько гигабайт конвертируются в браузере, в приложении для компьютера и в командной строке.

Можно ли конвертировать сам файл .db?

Да. Перетащите файл .db, .sqlite или .sqlite3: он читается в браузере и никуда не загружается. Текст с символами NUL и все цифры значения double приходят такими, как хранятся, а .dump может их обрезать.

Из каких версий SQLite может быть дамп?

Файлы баз данных SQLite начиная с 3.0, в UTF-8 или UTF-16, и дампы из .dump оболочки sqlite3 или из iterdump() в Python. Каждый тестовый файл и дамп создан в sqlite3 с 3.31 по 3.54, включая таблицы STRICT и WITHOUT ROWID, и сверен с источником ячейка за ячейкой.

Как определяются типы столбцов, если SQLite их не соблюдает?

Каждый столбец сохраняет объявленный тип, как и COLLATE NOCASE и RTRIM. STRICT опускается, поэтому скрипт загружается на любой версии начиная с 3.31.

Сохраняются ли INTEGER PRIMARY KEY и AUTOINCREMENT?

Да. INTEGER PRIMARY KEY и AUTOINCREMENT остаются как есть, а sqlite_sequence продолжается с того места, где его оставил дамп.

А представления и триггеры?

Они перечислены в отчете по имени и не конвертируются, чтобы вы могли создать их заново, когда таблицы будут загружены.

На каких версиях SQLite загружается скрипт?

SQLite 3.31 и новее. Каждый тестовый файл и дамп загружается на 3.31 и 3.54 и останавливается на первой ошибке, если что-то пойдет не так.