как вывести данные некоторых таблиц sqlite3?

<p>как вывести данные, и только данные, а не схему, некоторых таблиц sqlite3 базы данных (не всех таблиц)? дамп должен быть в формате sql, так как он должен быть легко повторно введен в базу данных позже и должен быть выполнен из командной строки. что-то вроде</p><pre><code>sqlite3 db .dump </code></pre><p>но без выгрузки схемы и выбора таблиц для выгрузки.</p>

<p>вы не говорите, что вы хотите сделать с сохраненным файлом.</p><p>я бы использовал следующее, чтобы получить файл csv, который я могу импортировать практически во все</p><pre><code>.mode csv -- use '.separator some\_string' for something other than a comma. .headers on .out file.csv select * from mytable; </code></pre><p>если вы хотите переустановить в другую базу данных sqlite, то:</p><pre><code>.mode insert <target\_table\_name> .out file.sql select * from mytable; </code></pre>

<p>вы можете сделать это, получая разницу команд .schema и .dump. например с помощью grep:</p><pre><code>sqlite3 some.db .schema > schema.sql sqlite3 some.db .dump > dump.sql grep -vx -f schema.sql dump.sql > data.sql </code></pre><p>файл <code>data.sql</code> будет содержать только данные без схемы, что-то вроде этого:</p><pre><code>begin transaction; insert into "table1" values ...; ... insert into "table2" values ...; ... commit; </code></pre><p>я надеюсь, это поможет вам.</p>

<p>не лучший способ, но при аренде не нужны внешние инструменты (кроме grep, который в любом случае является стандартным для * nix)</p><pre><code>sqlite3 database.db3 .dump | grep '^insert into "tablename"' </code></pre><p>но вам нужно выполнить эту команду для каждой таблицы, которую вы ищете.</p><p>обратите внимание, что это не включает схему.</p>

<p>вы можете указать один или несколько табличных аргументов для специальной команды .dump, например .<code>sqlite3 db ".dump 'table1' 'table2'"</code>.</p>

<p>любой ответ, который предлагает использовать grep для исключения строк <code>create</code> или просто получить строки <code>insert</code> из вывода <code>sqlite3 $db .dump, потерпит неудачу. команды create table перечисляют один столбец в каждой строке (поэтому исключая create, вы не получите все это), а значения в строках insert могут иметь встроенные новые строки (поэтому вы не можете получить только строки insert).for t in $(sqlite3 $db .tables); do echo -e ".mode insert $t\nselect * from $t;" done | sqlite3 $db > backup.sql </code></pre><p>протестировано на sqlite3 версии 3.6.20.</p><p>если вы хотите исключить определенные таблицы, вы можете отфильтровать их с помощью <code>$(sqlite $db .tables | grep -v -e one -e two -e three)</code>, или если вы хотите получить определенное подмножество, замените его на <code>one two three</code>.</p>

<p>в качестве улучшения ответа пола игана это можно сделать следующим образом:</p><pre><code>sqlite3 database.db3 '.dump "table1" "table2"' | grep '^insert' </code></pre><p>--или же--</p><pre><code>sqlite3 database.db3 '.dump "table1" "table2"' | grep -v '^create' </code></pre><p>предостережение, конечно, в том, что вам нужно установить grep.</p>

<p>в python или java или на любом языке высокого уровня .dump не работает. нам нужно закодировать преобразование в csv вручную. я даю пример python. другие примеры будут оценены:</p><pre><code>from os import path import csv def convert\_to\_csv(directory, db\_name): conn = sqlite3.connect(path.join(directory, db\_name + '.db')) cursor = conn.cursor() cursor.execute("select name from sqlite\_master where type='table';") tables = cursor.fetchall() for table in tables: table = table[0] cursor.execute('select * from ' + table) column\_names = [column\_name[0] for column\_name in cursor.description] with open(path.join(directory, table + '.csv'), 'w') as csv\_file: csv\_writer = csv.writer(csv\_file) csv\_writer.writerow(column\_names) while true: try: csv\_writer.writerow(cursor.fetchone()) except csv.error: break </code></pre><p>если у вас есть данные панели, другими словами, многие отдельные записи с идентификаторами добавляют это к внешнему виду, а также выводит сводную статистику:</p><pre><code> if 'id' in column\_names: with open(path.join(directory, table + '\_aggregate.csv'), 'w') as csv\_file: csv\_writer = csv.writer(csv\_file) column\_names.remove('id') column\_names.remove('round') sum\_string = ','.join('sum(%s)' % item for item in column\_names) cursor.execute('select round, ' + sum\_string +' from ' + table + ' group by round;') csv\_writer.writerow(['round'] + column\_names) while true: try: csv\_writer.writerow(cursor.fetchone()) except csv.error: break </code></pre>

<p>в соответствии с документацией sqlite для <a href="https://www.sqlite.org/cli.html">оболочка командной строки для sqlite</a> вы можете экспортировать таблицу sqlite (или часть таблицы) как csv, просто установив для "mode" значение "csv", а затем запустите запрос для извлечения нужных строк таблицы:</p><pre><code>sqlite> .header on sqlite> .mode csv sqlite> .once c:/work/dataout.csv sqlite> select * from tab1; sqlite> .exit </code></pre><p>затем с помощью команды ".import" импортируйте данные csv (значения, разделенные запятыми) в таблицу sqlite:</p><pre><code>sqlite> .mode csv sqlite> .import c:/work/dataout.csv tab1 sqlite> .exit </code></pre><p>пожалуйста, прочтите дополнительную документацию о двух рассматриваемых случаях: (1) таблица "tab1" ранее не существует и (2) таблица "tab1" уже существует.</p>

<p>лучший способ - взять код, который будет делать дамп sqlite3 db, за исключением частей схемы.</p><p>пример псевдокода:</p><pre><code>select 'insert into ' || tablename || ' values( ' || {for each value} ' quote(' || value || ')' (+ commas until final) || ')' from 'tablename' order by rowid desc </code></pre><p>см. <code>src/shell.c:838</code> (для sqlite-3.5.9) для фактического кода</p><p>вы можете даже взять эту оболочку, закомментировать части схемы и использовать это.</p>

<h1>обзор других возможных решений</h1><p><strong> включить только вставки </strong></p><pre><code>sqlite3 database.db3 .dump | grep '^insert into "tablename"' </code></pre><p>легко реализовать, но не получится, если в любой из ваших столбцов появятся новые строки</p><p><strong> режим вставки sqlite </strong></p><pre><code>for t in $(sqlite3 $db .tables); do echo -e ".mode insert $tnselect  from $t;" done | sqlite3 $db > backup.sql это удобное и настраиваемое решение, но оно не работает, если у ваших столбцов есть объекты blob-объектов типа geometry в пространственном объекте.<strong> diff dump с помощью схемы </strong>sqlite3 some.db .schema > schema.sql sqlite3 some.db .dump > dump.sql grep -v -f schema.sql dump > data.sql не уверен почему, но у меня не работаетдругое (новое) возможное решениевероятно, нет лучшего ответа на этот вопрос, но тот, который мне подходит, это grep вставки, принимая во внимание, что это новые строки в значениях столбцов с <a href="https://stackoverflow.com/a/7167115/930271">выражение вроде этого grep -pzo "(?s)^insert.);[ t]$" </code></pre><p>для выбора таблиц должен быть дамп. <code>.dump</code> допускает использование аргумента like для соответствия именам таблиц, но если этого недостаточно, возможно, лучше использовать простой скрипт</p><pre><code>tables='table1 table2 table3' echo '' > /tmp/backup.sql for t in $tables ; do echo -e ".dump ${t}" | sqlite3 database.db3 | grep -pzo "(?s)^insert.*?\);$" >> /tmp/backup.sql done или что-то более сложное, чтобы уважать внешние ключи и инкапсулировать весь дамп только в одной транзакцииtables='table1 table2 table3' echo 'begin transaction;' > /tmp/backup.sql echo '' >> /tmp/backup.sql for t in $tables ; do echo -e ".dump ${t}" | sqlite3 $1 | grep -pzo "(?s)^insert.*?\);$" | grep -v -e 'pragma foreign\_keys=off;' -e 'begin transaction;' -e 'commit;' >> /tmp/backup.sql done echo '' >> /tmp/backup.sql echo 'commit;' >> /tmp/backup.sql </code></pre><p>учтите, что выражение grep не будет выполнено, если <code>);</code> - строка, присутствующая в любом из столбцов.</p><p>восстановить его (в базе данных с уже созданными таблицами)</p><pre><code>sqlite3 -bail database.db3 < /tmp/backup.sql </code></pre>

<p>эта версия хорошо работает с символами новой строки внутри вставок:</p><p><code>sqlite3 database.sqlite3 .dump | grep -v '^create'</code></p><p>на практике исключаются все строки, начинающиеся с <code>create</code>, которые с меньшей вероятностью содержат символы новой строки</p>

<p>ответ от retracile должен быть самым близким, но он не работает для моего случая. один запрос вставки просто сломался в середине, и экспорт просто остановился. не уверен, в чем причина. однако он прекрасно работает во время <code>.dump</code>.</p><p>наконец, я написал инструмент для разделения sql, сгенерированного из <code>.dump</code>:</p><p> <a href="https://github.com/motherapp/sqlite\_sql\_parser/">https://github.com/motherapp/sqlite\_sql\_parser/</a> </p>