web-dev-qa-db-fra.com

Comment vider un fichier stocké dans une base de données sqlite en tant que blob?

J'ai une base de données sqlite3. Une colonne a le type TEXT et contient des blobs que je voudrais enregistrer sous forme de fichier. Ce sont des fichiers compressés.

Le résultat de la commande sqlite3 db.sqlite3 ".dump" est le suivant:

INSERT INTO "data" VALUES(1,'objects','object0.gz',X'1F8B080000000000000 [.. a few thousands of hexadecimal characters ..] F3F5EF')

Comment puis-je extraire les données binaires du fichier sqlite dans un fichier à l'aide de la ligne de commande?

30
alecail

sqlite3 ne peut pas sortir directement des données binaires. Vous devez donc convertir les données en hexdump, utiliser cut pour extraire les chiffres hexadécimaux du littéral blob et utiliser xxd (une partie du paquetage vim) pour convertir le hexdump en binaire:

sqlite3 my.db "SELECT quote(MyBlob) FROM MyTable WHERE id = 1;"  \
| cut -d\' -f2                                                   \
| xxd -r -p                                                      \
> object0.gz

Avec SQLite 3.8.6 ou version ultérieure, le shell de ligne de commande inclut l'extension fileio, qui implémente la fonction writefile :

sqlite3 my.db "SELECT writefile('object0.gz', MyBlob) FROM MyTable WHERE id = 1"
55
CL.

Je devais faire quelques changements mineurs sur la réponse de CL , pour que cela fonctionne pour moi:

  • La structure de la commande qu'il utilise ne contient pas le nom de la base de données. La syntaxe que j'utilise ressemble à ceci:

    sqlite3 mydatabase.sqlite3 "Select quote(BlobField) From TableWithBlod Where StringKey = '1';" | ...
    
  • La façon dont il utilise la commande cut ne fonctionne pas sur ma machine. La manière correcte pour moi est:

    cut -d "'" -f2
    

Donc, la commande finale serait quelque chose comme:

sqlite3 mydatabase.sqlite3 "Select quote(BlobField) From TableWithBlod Where StringKey = '1';" | cut -d "'" -f2 | xxd -r -p > myfile.extension

Et dans mon cas:

sqlite3 osm-carto_z14_m8_m.mbtiles "select quote(images.tile_data) from images where images.tile_id = '1';" | cut -d "'" -f2 | xxd -r -p > image.png
3
Canella

Dans mon cas, j'utilise "hex" au lieu de "quote" pour récupérer une image de la base de données, et nul besoin de "couper" dans le canal de commande. Par exemple:

sqlite3 fr.db "select hex(bmp) from reg where id=1" | xxd -r -p > 2.png
1
鄭大大