Archiver une base de données avec archive
Traduction automatique provisoire, non révisée. En cas de doute, consultez la version anglaise, qui fait foi.
kent archive écrit une base de données dans une archive d'échange en un seul
fichier : un zip contenant un fichier NDJSON par table
contenant des données, un manifeste qui les décrit, et le schéma source.
Il est en lecture seule. kent archive ouvre la base de données dans le mode
lecture seule de SQLite et n'y écrit rien.
Laquelle voulez-vous, archive ou sqldump
Kent a deux façons de sortir d'une base de données, et elles servent à des tâches différentes. Choisir la mauvaise vous coûte une étape de conversion plus tard.
sqldump |
archive | |
|---|---|---|
| Produit | Un script .sql | Un zip de fichiers NDJSON |
| Pour | Recréer la base de données | Confier les données à un autre programme |
| Relu par | sqlite3, ou tout outil SQLite | Tout langage doté d'une bibliothèque zip et d'une bibliothèque JSON |
| Peut aller dans un tube | Oui, quand --out est
omise | Non, un zip ne peut pas être écrit sur la sortie standard |
Si vous voulez récupérer vos données dans SQLite, utilisez sqldump. Si vous
voulez les lire en Python, utilisez archive.
Synopsis
kent archive --in <dbfilename> --out <archive>
Arguments
| Option | Requise | Description |
|---|---|---|
--in <dbfilename> | Oui | Chemin d'une base de
données .sqlite existante à lire. |
--out <archive> | Oui | Où écrire l'archive. |
Les deux sont requises. Contrairement à sqldump, il n'y
a pas de forme sur sortie standard sur laquelle se rabattre, car un zip ne peut pas être
écrit dans un tube.
$ kent archive --in mydata.sqlite
missing required flag: --out
usage: kent archive --in <dbfilename> --out <archive>
Une remarque sur le nom du fichier
.kent est l'extension de ces archives. Elle nomme un format défini, le
manifeste, le schéma et la disposition par table décrits ci-dessous, plutôt qu'un dossier
arbitraire dont le contenu serait à vous de réarranger.
Kent ne l'impose pas, et c'est délibéré. --out prend le chemin que vous lui
donnez, aucun suffixe n'est vérifié ni ajouté, et le résultat est un fichier zip ordinaire
que n'importe quel outil zip ouvre, quel que soit son nom. En nommer un
mydata.zip vous donne une archive parfaitement valide, elle ne dit simplement
pas ce qu'elle est.
Ce que contient l'archive
mydata.kent
mimetype always first, uncompressed: application/vnd.venhola.kent
manifest.json what this archive is, and what is in it
schema.sql the source schema, in the same form kent sqldump --schema-only emits
tables/00000001.jsonl one JSON object per line, one line per row
tables/00000002.jsonl the manifest says which table each number holds
...
Les fichiers de table sont numérotés plutôt que nommés d’après leur table. Un nom de
table peut contenir des caractères qu’un nom de fichier n’accepte pas, comme une apostrophe
double, un deux-points ou une barre oblique ; Kent écrit donc
tables/00000001.jsonl, tables/00000002.jsonl et ainsi de suite,
dans l’ordre d’écriture des tables. Le numéro n’indique pas quelle table il contient :
c’est le champ tables[].file du manifeste qui fait le lien, et c’est pourquoi
l’exemple ci-dessous lit d’abord le manifeste.
L'entrée mimetype est ce qui rend un .kent reconnaissable.
Toutes les autres entrées sont compressées : sans elle, rien n'identifie le fichier tant que
quelque chose n'en a pas décompressé une partie. Ces 28 octets sont stockés sans compression
tout au début, là où un outil peut les lire directement dans le fichier, la même astuce
qu'EPUB, pour la même raison. Vous pouvez l'ignorer quand vous lisez une archive vous-même ;
kent restore, lui, la vérifie et refuse une archive qui ne la porte pas.
Une table sans lignes ne produit pas de fichier. Elle est listée dans le tableau
skipped du manifeste avec un motif, de sorte qu'un programme qui lit l'archive
peut distinguer une table vide d'une table laissée de côté ou que le schéma source n'a jamais
eue. Un schéma Cordelia compte 129 tables et une base réelle en peuple environ 15 : la plus
grande partie de ce que décrit le manifeste est donc ce qui n'y est pas.
La lire
La bibliothèque standard de Python suffit, aucun paquet tiers, et nul besoin d'avoir Kent ou Cordelia installés sur la machine qui lit :
import zipfile, json
with zipfile.ZipFile('mydata.kent') as z:
manifest = json.loads(z.read('manifest.json'))
files = {t['name']: t['file'] for t in manifest['tables']}
with z.open(files['Session']) as f:
for line in f:
row = json.loads(line)
print(row['start_time'], row['sport_id'])
Deux choses dans cette boucle sont délibérées. Elle lit une ligne à la fois plutôt que de charger une table en mémoire, car une seule table peut atteindre des dizaines de milliers de lignes. Et elle n'ouvre que la table qu'elle veut, le reste de l'archive n'est jamais décompressé, ce qui est la raison pour laquelle le format est un zip de fichiers séparés plutôt qu'un seul gros document JSON.
Les lignes sont des objets JSON plutôt que des tableaux, si bien qu'on atteint une colonne
par son nom. Cela répète chaque nom de colonne sur chaque ligne, ce qui ne coûte rien en
pratique : la répétition est exactement ce que supprime la compression zip, et
row['sport_id'] est bien plus facile à écrire correctement que
row[47].
Comment les valeurs traversent
Les classes de stockage de SQLite survivent au voyage :
| Dans SQLite | Dans l'archive | En Python |
|---|---|---|
INTEGER | Un nombre JSON | int |
REAL | Un nombre JSON, toujours avec un point décimal ou un exposant | float |
TEXT | Une chaîne JSON | str |
BLOB | {"$blob": "<base64>"} |
dict |
NULL | null | None |
Un REAL de valeur entière garde son point décimal pour ne pas se relire comme
un entier. Un blob est enveloppé dans un objet plutôt qu'écrit comme une simple chaîne, parce
qu'un texte base64 est indiscernable d'un texte ordinaire qui ressemblerait à du base64.
Une valeur ne survit pas. Not-a-number et l’infini sont écrits
0.0, et un zéro substitué ne se distingue pas d’un zéro mesuré.
sqldump écrit not-a-number en NULL.
Le manifeste
Un seul fichier répond à toutes les questions de structure sur l'archive : un programme le lit une fois et sait ensuite ce qu'il tient :
{
"format_version": 1,
"kent": "1.3.4",
"cordelia": "1.3.3",
"exported": "2026-08-29T14:02:11Z",
"schema": { "user_version": 2 },
"source": { "path": "mydata.sqlite", "size_bytes": 5492736,
"modified": "2026-08-29T00:08:26Z" },
"counts": { "tables_in_schema": 129, "tables_exported": 15,
"tables_skipped": 114, "total_rows": 53673 },
"tables": [
{ "name": "Session", "rows": 26, "file": "tables/00000001.jsonl",
"columns": [ { "name": "sport_id", "type": "INTEGER" } ] }
],
"skipped": [ { "name": "AntRx", "reason": "empty" } ]
}
| Champ | Ce qu'il vous dit |
|---|---|
format_version | La version de la disposition de l'archive elle-même. Un programme qui ne reconnaît pas le numéro devrait refuser l'archive plutôt que de deviner. |
kent, cordelia | Quelles versions ont produit l'archive. Celle de Cordelia est celle qui identifie le schéma. Voir Exporter une base de données avec sqldump pour la raison. |
schema.user_version | La version de schéma de la base source, lisible sans ouvrir la moindre donnée de table. |
source | Le chemin, la taille et la date de modification du fichier d'où cela provient. Taille et date ensemble répondent à « est-ce bien une archive du fichier que je crois ? », ce qu'un chemin seul ne fait pas. |
counts.tables_in_schema | Comptées dans la base source, pas dans cette compilation de Cordelia : une archive d'une base ancienne rapporte donc ce que cette base avait réellement. |
columns | Le type SQLite déclaré de chaque colonne, dans
l'ordre. C'est l'autorité sur la façon d'interpréter une valeur, un 1 JSON
seul ne peut pas vous dire si la colonne est un entier ou un réel de valeur
entière. |
skipped | Les tables sans fichier dans l'archive, et pourquoi.
Aujourd'hui le seul motif est empty. |
Les noms exported et tables_exported décrivent l'opération
plutôt que la commande qui l'a lancée, et ils correspondent à la ligne
-- exported: d'un en-tête kent sqldump. Ce ne
sont pas un reliquat de l'ancien nom de la commande.
Les tables de référence voyagent avec elle
L'archive inclut les tables de référence pré-remplies de Cordelia,
better_labels_definitions et better_labels_lookup, environ
19 700 lignes à elles deux, plutôt que de les laisser de côté comme du
volume.
C'est ce qui permet à l'archive de répondre à ses propres questions. Un
sport_id valant 5 ne signifie rien tout seul ; le résoudre en un
nom de sport exige ces deux tables. Sans elles, un script détenant une archive aurait besoin
d'une base Cordelia distincte rien que pour interpréter ce qu'il a déjà. Elles se compressent
en outre extrêmement bien, un texte court et très répétitif est proche du meilleur cas pour
un zip.
Une ancienne base est archivée, pas refusée
Comme sqldump, et contrairement à
info, details et
files, cette commande ne refuse pas une base dont la
version de schéma diffère de celle attendue par cette compilation. Le manifeste consigne la
version qu'elle a trouvée, si bien que l'archive énonce ce qu'était réellement la
source.
Une exécution qui échoue ne laisse aucune archive derrière elle, ni archive partielle. Un
chemin donné à --in qui n'existe pas est signalé comme manquant et n'est
pas créé :
$ kent archive --in nope.sqlite --out out.kent
kent archive: nope.sqlite does not exist
$ echo $?
1
Un répertoire temporaire apparaît pendant l'exécution
Les tables sont écrites dans un répertoire nommé d'après l'archive suivi de
.staging, à côté de l'endroit où l'archive va aller, et zippées depuis là plutôt
que conservées en mémoire, une seule table peut être très grosse. Le répertoire est supprimé
quand la commande se termine, y compris en cas d'échec. Si vous en voyez un subsister après
que Kent s'est terminé, cela vaut la peine d'être
signalé.
Cela veut aussi dire que la destination a besoin de place pour l'archive et son contenu préparé en même temps.
Relire une archive dans une base de données
kent restore reconstruit un fichier
.sqlite à partir d'une archive :
$ kent restore --in mydata.kent --out restored.sqlite
Il reproduit la base de données dont provient l'archive plutôt que de la mettre à jour, version de schéma comprise, si bien qu'une archive d'une ancienne base restaure une ancienne base. Chaque valeur et sa classe de stockage survivent, hormis pas-un-nombre et l'infini, que l'archive ne pouvait pas transporter au départ.
Voir aussi Messages d'erreur et codes de sortie et Exporter une base de données avec sqldump.
Voir aussi
- Codes de sortie
- Exporter une base de données avec sqldump
- Établir un rapport sur une base de données avec info
- Rapport complet avec details
- Lister les fichiers importés avec files
- Rapports de bogues et demandes de fonctionnalités
- Reconstruire une base de données avec restore
- Messages d'erreur et codes de sortie