Как сбрасывать данные из некоторых таблиц SQLite3?

Как мне сбросить данные и только данные, а не схему некоторых таблиц SQLite3 базы данных (не все таблицы)? Дамп должен быть в формате SQL, так как он должен быть легко повторно введен в базу данных позже и должен выполняться из командной строки. Что-то вроде

sqlite3 db .dump

но без сброса схемы и выбора таблиц для дампа.

Ответ 1

Вы не говорите, что хотите делать с выгруженным файлом.

Я бы использовал следующее, чтобы получить файл CSV, который я могу импортировать почти во все

.mode csv 
-- use '.separator SOME_STRING' for something other than a comma.
.headers on 
.out file.dmp 
select * from MyTable;

Если вы хотите повторно вставить в другую базу данных SQLite, выполните следующие действия:

.mode insert <target_table_name>
.out file.sql 
select * from MyTable;

Ответ 2

Вы можете сделать это, получив разницу в командах .schema и .dump. например, с grep:

sqlite3 some.db .schema > schema.sql
sqlite3 some.db .dump > dump.sql
grep -vx -f schema.sql dump.sql > data.sql

data.sql файл будет содержать только данные без схемы, что-то вроде этого:

BEGIN TRANSACTION;
INSERT INTO "table1" VALUES ...;
...
INSERT INTO "table2" VALUES ...;
...
COMMIT;

Надеюсь, это поможет вам.

Ответ 3

Не лучший способ, но при аренде не нужны внешние инструменты (кроме grep, который является стандартным на * nix-блоках в любом случае)

sqlite3 database.db3 .dump | grep '^INSERT INTO "tablename"'

но вам нужно выполнить эту команду для каждой таблицы, которую вы ищете.

Обратите внимание, что это не включает схему.

Ответ 4

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

Ответ 5

Любой ответ, который предлагает использовать grep для исключения строк CREATE или просто захватить строки INSERT с выхода 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

Протестировано на sqlite3 версии 3.6.20.

Если вы хотите исключить определенные таблицы, вы можете отфильтровать их с помощью $(sqlite $DB .tables | grep -v -e one -e two -e three), или если вы хотите получить определенное подмножество, замените его на one two three.

Ответ 6

В качестве улучшения ответа Павла Игана это можно сделать следующим образом:

sqlite3 database.db3 '.dump "table1" "table2"' | grep '^INSERT'

- или -

sqlite3 database.db3 '.dump "table1" "table2"' | grep -v '^CREATE'

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

Ответ 7

В Python или Java или любом языке высокого уровня .dump не работает. Нам нужно закодировать преобразование в CSV вручную. Я даю пример Python. Другие, примеры были бы оценены:

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

Если у вас есть "данные панели", другими словами, многие отдельные записи с идентификатором добавляют это в внешний вид, а также выводят сводную статистику:

        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 

Ответ 8

В соответствии с документацией SQLite для командной строки Shell для SQLite вы можете экспортировать таблицу SQLite (или часть таблицы) в формате CSV, просто установив "режим" в "csv", а затем запустите запрос, чтобы извлечь нужные строки таблицы:

sqlite> .header on
sqlite> .mode csv
sqlite> .once c:/work/dataout.csv
sqlite> SELECT * FROM tab1;
sqlite> .exit

Затем используйте команду ".import" для импорта данных CSV (данные, разделенные запятыми) в таблицу SQLite:

sqlite> .mode csv
sqlite> .import C:/work/dataout.csv tab1
sqlite> .exit

Прочитайте дальнейшую документацию по двум рассмотренным случаям: (1) Таблица "tab1" ранее не существует и (2) таблица "tab1" уже существует.

Ответ 9

Вы можете использовать такой инструмент, как SQLite Administrator.

Там длинный список таких инструментов здесь.

Ответ 10

Лучший способ - взять код, который сделает dump sqlite3 db, за исключением частей схемы.

Пример псевдокода:

SELECT 'INSERT INTO ' || tableName || ' VALUES( ' || 
  {for each value} ' quote(' || value || ')'     (+ commas until final)
|| ')' FROM 'tableName' ORDER BY rowid DESC

Смотрите: src/shell.c:838 (для sqlite-3.5.9) для фактического кода

Вы даже можете просто взять эту оболочку и прокомментировать части схемы и использовать ее.

Ответ 11

Эта версия хорошо работает с новыми строками внутри вставок:

sqlite3 database.sqlite3 .dump | grep -v '^CREATE'

На практике исключает все строки, начинающиеся с CREATE, которые с меньшей вероятностью будут содержать символы новой строки

Ответ 12

Обзор других возможных решений

Включить только INSERT

sqlite3 database.db3 .dump | grep '^INSERT INTO "tablename"'

Легко реализовать, но он потерпит неудачу, если какой-либо из ваших столбцов включает новые строки

Режим вставки SQLite

for t in $(sqlite3 $DB .tables); do
    echo -e ".mode insert $t\nselect * from $t;"
done | sqlite3 $DB > backup.sql

Это приятное и настраиваемое решение, но оно не работает, если в ваших столбцах есть объекты с блобом типа типа "Геометрия" в пространственном формате

Сбросить дамп со схемой

sqlite3 some.db .schema > schema.sql
sqlite3 some.db .dump > dump.sql
grep -v -f schema.sql dump > data.sql

Не знаю, почему, но не работает для меня

Другое (новое) возможное решение

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

grep -Pzo "(?s)^INSERT.*\);[ \t]*$"

Чтобы выбрать таблицы, которые нужно сбросить, .dump допускает аргумент LIKE для соответствия именам таблиц, но если этого недостаточно, возможно, проще script

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

Учтите, что выражение grep не будет выполнено, если ); является строкой, присутствующей в любом столбце

Чтобы восстановить его (в базе данных с уже созданными таблицами)

sqlite3 -bail database.db3 < /tmp/backup.sql

Ответ 13

Ответ от retracile должен быть самым близким, но это не работает для моего дела. Один запрос вставки просто сломался посередине, и экспорт просто остановился. Не знаете, в чем причина. Однако он отлично работает во время .dump.

Наконец, я написал инструмент для разделения SQL, сгенерированного из .dump:

https://github.com/motherapp/sqlite_sql_parser/

Ответ 14

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