Leve um banco SQLite para um SQLite mais antigo ou mais novo
Solte um arquivo de banco de dados SQLite (.db, .sqlite, .sqlite3) ou o SQL que o .dump do sqlite3 escreve, e baixe um script que carrega no SQLite 3.31 ou posterior. Cada coluna mantém seu tipo declarado e sua collation, STRICT é omitido para que versões mais antigas aceitem as tabelas, e cada mudança é listada no relatório.
18 linhas convertidas, nenhuma correção, nenhuma rejeitada
Tabelas em shop_2024_sqlite.sqlDump do SQLite · gerado por sqlite3 · utf-8
customers8 linhas
7 colunas 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 linhas
9 colunas 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
Não convertidos
- Visão order_totals
- Gatilho orders_shipped
Cada banco de dados escreve estes objetos na sua própria linguagem. Reescreva-os para o 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;
Correções
Nada precisou de correção.
Para revisar
- 2 visões, gatilhos, rotinas ou eventos não foram convertidos; o relatório lista cada um. Recrie-os manualmente no SQLite.
Seu arquivo é convertido neste computador e nunca é enviado.
Outros exemplos:
O que muda entre o arquivo e o script
Cada linha é uma regra que o conversor aplica, com a linha do relatório que ele escreve quando a regra muda algo nos seus dados.
declared types (any text: VARCHAR(255), DATETIME, BOOLEAN, JSON or none)
o tipo em que cabem todos os valores da coluna
Os mesmos tipos declarados, então os valores carregam como foram armazenados.
BOOLEAN, BOOL
INTEGER 0 ou 1 com um CHECK
Quando todo valor é 0 ou 1; uma coluna que também tem outros valores os mantém como números ou texto.
TEXT, VARCHAR(n), CHAR(n), CLOB
o tipo declarado, mantido como está
O SQLite nunca impõe um tamanho; um tamanho declarado só vale quando todo valor cabe nele.
DECIMAL(p,s), NUMERIC
o tipo exato quando todo valor cabe nele, senão um double
O SQLite os guarda como inteiros ou doubles; uma precisão declarada só vale quando os valores cabem nela.
BLOB, and columns holding bytes
BLOB
Bytes continuam bytes; texto e números na mesma coluna são mantidos como seus bytes.
DATE, DATETIME, TIMESTAMP holding ISO 8601 text
DATE, DATETIME como texto ISO 8601
Quando todo valor é uma data ou uma data e hora; números epoch e outros textos mantêm seus valores como estão.
JSON holding JSON text
TEXT
Quando todo valor é um objeto ou array JSON.
Infinity in REAL columns
9e999, o infinito próprio do SQLite
O SQLite escreve o infinito como um literal que estoura, que ao carregar volta a ser infinito.
INTEGER PRIMARY KEY, AUTOINCREMENT
INTEGER PRIMARY KEY, AUTOINCREMENT mantido
Só uma coluna declarada exatamente como INTEGER PRIMARY KEY é o rowid; cada linha mantém seu id, e o contador começa depois do maior id já atribuído.
COLLATE NOCASE
COLLATE NOCASE
A mesma collation.
generated columns
colunas geradas, STORED ou VIRTUAL como na origem
O SQLite as calcula do mesmo jeito.
generated columns with functions IntoSQL doesn't write, and the || operator
uma coluna simples
Uma fórmula que não pode ser escrita deixa uma coluna simples e uma linha no relatório; o dump não tem valores para colunas geradas.
Linha do relatório: generated_not_translated
defaults with functions IntoSQL doesn't write (strftime, randomblob)
sem valor padrão
Um valor padrão que não pode ser escrito fica de fora e é informado; CURRENT_TIMESTAMP e datetime('now') são escritos.
Linha do relatório: default_not_translated
CHECK constraints
traduzidos
Os mesmos CHECKs, testados à medida que cada linha carrega.
CHECK constraints with functions IntoSQL doesn't write
não criado
Um CHECK que não pode ser escrito fica de fora e é informado.
Linha do relatório: check_skipped
partial and expression indexes
não criado
O IntoSQL escreve índices sobre colunas inteiras; crie os outros de novo depois da carga.
Linha do relatório: index_skipped
foreign keys (unenforced unless PRAGMA foreign_keys=ON)
as mesmas chaves estrangeiras, listadas por PRAGMA foreign_key_check
O SQLite só verifica chaves estrangeiras quando instruído, então linhas sem pai são comuns: elas carregam, e a chave fica sem verificação com um aviso, em vez de parar a carga.
foreign keys to tables the dump doesn't create
não criada
Uma chave não pode apontar para uma tabela que não existe.
Linha do relatório: foreign_key_skipped
primary keys holding NULL, and NOT NULL columns with values that become NULL
NOT NULL removido
O SQLite deixa uma chave primária que não seja o rowid conter NULL; a coluna não pode ser NOT NULL no destino, senão a carga pararia.
Linha do relatório: not_null_relaxed
views, triggers and virtual tables (FTS, R*Tree)
listados no relatório
O código deles é escrito na linguagem própria do SQLite, e tabelas virtuais precisam dos módulos do SQLite; eles são listados para você recriar. As tabelas internas deles não são copiadas.
Linha do relatório: not_converted_objects
dumps without CREATE TABLE (--data-only)
tipos lidos dos valores
Um dump só de dados tem apenas linhas, então os tipos vêm dos valores e as colunas são numeradas.
Linha do relatório: no_schema
expressions in INSERT values other than the text functions dumps write
NULL
unistr(), replace(), char() e || são avaliados como o shell os escreve; as outras expressões não podem ser avaliadas sem um banco de dados.
Linha do relatório: expression_value
NUL characters in text
mantido
O shell sqlite3 e o Python cortam o texto em um caractere NUL ao gerar o dump, então só o que vem antes dele está no dump.
text that isn't valid UTF-8
os bytes inválidos como o caractere de substituição
Os dumps escrevem esse texto como bytes brutos; o script é UTF-8.
Linha do relatório: invalid_utf8_replaced
text decoded twice (ñ)
copiado como está
O dump contém exatamente esses caracteres, então eles são copiados; o relatório os aponta.
Linha do relatório: mojibake_suspected
| No arquivo | No script | Linha do relatório |
|---|---|---|
| declared types (any text: VARCHAR(255), DATETIME, BOOLEAN, JSON or none) | o tipo em que cabem todos os valores da colunaOs mesmos tipos declarados, então os valores carregam como foram armazenados. | |
| BOOLEAN, BOOL | INTEGER 0 ou 1 com um CHECKQuando todo valor é 0 ou 1; uma coluna que também tem outros valores os mantém como números ou texto. | |
| TEXT, VARCHAR(n), CHAR(n), CLOB | o tipo declarado, mantido como estáO SQLite nunca impõe um tamanho; um tamanho declarado só vale quando todo valor cabe nele. | |
| DECIMAL(p,s), NUMERIC | o tipo exato quando todo valor cabe nele, senão um doubleO SQLite os guarda como inteiros ou doubles; uma precisão declarada só vale quando os valores cabem nela. | |
| BLOB, and columns holding bytes | BLOBBytes continuam bytes; texto e números na mesma coluna são mantidos como seus bytes. | |
| DATE, DATETIME, TIMESTAMP holding ISO 8601 text | DATE, DATETIME como texto ISO 8601Quando todo valor é uma data ou uma data e hora; números epoch e outros textos mantêm seus valores como estão. | |
| JSON holding JSON text | TEXTQuando todo valor é um objeto ou array JSON. | |
| Infinity in REAL columns | 9e999, o infinito próprio do SQLiteO SQLite escreve o infinito como um literal que estoura, que ao carregar volta a ser infinito. | |
| INTEGER PRIMARY KEY, AUTOINCREMENT | INTEGER PRIMARY KEY, AUTOINCREMENT mantidoSó uma coluna declarada exatamente como INTEGER PRIMARY KEY é o rowid; cada linha mantém seu id, e o contador começa depois do maior id já atribuído. | |
| COLLATE NOCASE | COLLATE NOCASEA mesma collation. | |
| generated columns | colunas geradas, STORED ou VIRTUAL como na origemO SQLite as calcula do mesmo jeito. | |
| generated columns with functions IntoSQL doesn't write, and the || operator | uma coluna simplesUma fórmula que não pode ser escrita deixa uma coluna simples e uma linha no relatório; o dump não tem valores para colunas geradas. | generated_not_translated |
| defaults with functions IntoSQL doesn't write (strftime, randomblob) | sem valor padrãoUm valor padrão que não pode ser escrito fica de fora e é informado; CURRENT_TIMESTAMP e datetime('now') são escritos. | default_not_translated |
| CHECK constraints | traduzidosOs mesmos CHECKs, testados à medida que cada linha carrega. | |
| CHECK constraints with functions IntoSQL doesn't write | não criadoUm CHECK que não pode ser escrito fica de fora e é informado. | check_skipped |
| partial and expression indexes | não criadoO IntoSQL escreve índices sobre colunas inteiras; crie os outros de novo depois da carga. | index_skipped |
| foreign keys (unenforced unless PRAGMA foreign_keys=ON) | as mesmas chaves estrangeiras, listadas por PRAGMA foreign_key_checkO SQLite só verifica chaves estrangeiras quando instruído, então linhas sem pai são comuns: elas carregam, e a chave fica sem verificação com um aviso, em vez de parar a carga. | |
| foreign keys to tables the dump doesn't create | não criadaUma chave não pode apontar para uma tabela que não existe. | foreign_key_skipped |
| primary keys holding NULL, and NOT NULL columns with values that become NULL | NOT NULL removidoO SQLite deixa uma chave primária que não seja o rowid conter NULL; a coluna não pode ser NOT NULL no destino, senão a carga pararia. | not_null_relaxed |
| views, triggers and virtual tables (FTS, R*Tree) | listados no relatórioO código deles é escrito na linguagem própria do SQLite, e tabelas virtuais precisam dos módulos do SQLite; eles são listados para você recriar. As tabelas internas deles não são copiadas. | not_converted_objects |
| dumps without CREATE TABLE (--data-only) | tipos lidos dos valoresUm dump só de dados tem apenas linhas, então os tipos vêm dos valores e as colunas são numeradas. | no_schema |
| expressions in INSERT values other than the text functions dumps write | NULLunistr(), replace(), char() e || são avaliados como o shell os escreve; as outras expressões não podem ser avaliadas sem um banco de dados. | expression_value |
| NUL characters in text | mantidoO shell sqlite3 e o Python cortam o texto em um caractere NUL ao gerar o dump, então só o que vem antes dele está no dump. | |
| text that isn't valid UTF-8 | os bytes inválidos como o caractere de substituiçãoOs dumps escrevem esse texto como bytes brutos; o script é UTF-8. | invalid_utf8_replaced |
| text decoded twice (ñ) | copiado como estáO dump contém exatamente esses caracteres, então eles são copiados; o relatório os aponta. | mojibake_suspected |
Carregue o script no SQLite
O script cria as tabelas, copia as linhas e depois adiciona chaves, índices e chaves estrangeiras, então carrega rápido e para no primeiro erro.
sqlite3 -bail mydb.sqlite < sqlite.sqlite.sqlAs chaves estrangeiras são declaradas em cada tabela e as linhas carregam com a verificação de chaves estrangeiras desligada. Depois o script lista cada linha que aponta para uma linha que não existe, em vez de falhar no meio do caminho.
Para um dump grande, carregue em um arquivo novo em um disco local. O script carrega tudo em uma transação com a sincronização desligada, então roda na velocidade do disco, e uma carga interrompida no meio não deixa tabelas incompletas.
A linha de comando carrega o arquivo direto em um banco SQLite, sem escrever um script. É grátis.
Gere o dump do SQLite para o melhor resultado
O conversor lê o que o dump contém. Estas opções mantêm mais dos seus dados nele:
- O próprio arquivo do banco é convertido como está, lido página por página no navegador. Feche antes o app que escreve nele, para que nenhuma mudança fique para trás no arquivo -wal.
- sqlite3 app.db .dump > app.sql escreve o mesmo banco de dados como SQL, que também é convertido, em .sql ou .sql.gz.
- O DB Browser for SQLite escreve esse SQL com File, Export, Database to SQL file, e o iterdump() do Python também.
O que não é convertido
Views, triggers, procedures, funções e outros objetos escritos na própria linguagem do SQLite aparecem no relatório pelo nome, nunca são descartados em silêncio, para você conferir cada um com a versão do SQLite em que vai carregar antes de recriá-lo.
Perguntas sobre levar o SQLite entre versões
Não encontrou a resposta? Escreva para nós pela página de contato e uma pessoa responde. Página de contato
Meu dump é enviado?
Não. O conversor roda no seu navegador e lê o dump do seu disco em partes, então ele nunca sai do seu computador. O app para desktop e a linha de comando também convertem no seu computador.
Qual o tamanho máximo do dump?
O conversor nunca guarda o dump inteiro na memória: ele lê o arquivo duas vezes, por intervalos, e escreve o script à medida que avança. Dumps de vários gigabytes são convertidos no navegador, no app para desktop e com a linha de comando.
Posso converter o próprio arquivo .db?
Sim. Solte o arquivo .db, .sqlite ou .sqlite3: ele é lido no navegador e nunca é enviado. Textos com caracteres NUL e todos os dígitos de um double chegam como foram armazenados, algo que um .dump pode cortar.
De quais versões do SQLite o dump pode vir?
Arquivos de banco de dados do SQLite 3.0 em diante, em UTF-8 ou UTF-16, e dumps do .dump do shell sqlite3 ou do iterdump() do Python. Cada arquivo e dump de teste vem do sqlite3 3.31 a 3.54, incluindo tabelas STRICT e WITHOUT ROWID, e é comparado com a origem célula por célula.
Como os tipos de coluna são decididos quando o SQLite não os impõe?
Cada coluna mantém seu tipo declarado, assim como COLLATE NOCASE e RTRIM. STRICT fica de fora, então o script carrega em todas as versões a partir do 3.31.
INTEGER PRIMARY KEY e AUTOINCREMENT são mantidos?
Sim. INTEGER PRIMARY KEY e AUTOINCREMENT ficam como estão, e sqlite_sequence continua de onde o dump parou.
E as visões e os gatilhos?
Eles aparecem no relatório pelo nome e não são convertidos, para que você possa recriá-los quando as tabelas estiverem prontas.
Em quais versões do SQLite o script carrega?
SQLite 3.31 e posteriores. Cada arquivo e dump de teste carrega no 3.31 e no 3.54, parando no primeiro erro se algo der errado.