Как сбрасывать данные из некоторых таблиц 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.