데이터베이스의 일부 SQLite3 테이블 (모든 테이블이 아님)의 데이터는 물론 스키마가 아닌 데이터 만 덤프하는 방법은 무엇입니까? 덤프는 나중에 데이터베이스에 쉽게 다시 입력해야하며 명령 행에서 수행해야하므로 SQL 형식이어야합니다. 같은 것
sqlite3 db .dump
그러나 스키마를 덤프하지 않고 덤프 할 테이블을 선택하지 않아도됩니다.
덤프 된 파일로 수행하려는 작업을 말하지 않습니다.
다음을 사용하여 거의 모든 파일로 가져올 수있는 CSV 파일을 얻습니다.
.mode csv
-- use '.separator SOME_STRING' for something other than a comma.
.headers on
.out file.csv
select * from MyTable;
다른 SQLite 데이터베이스에 다시 삽입하려면 다음을 수행하십시오.
.mode insert <target_table_name>
.out file.sql
select * from MyTable;
.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;
이것이 도움이되기를 바랍니다.
최선의 방법은 아니지만 외부 도구가 필요하지 않습니다 (어쨌든 * nix 박스의 표준 인 grep 제외)
sqlite3 database.db3 .dump | grep '^INSERT INTO "tablename"'
그러나 찾고있는 각 테이블에 대해이 명령을 수행해야합니다.
여기에는 스키마가 포함되지 않습니다.
.dump 특수 명령에 하나 이상의 테이블 인수를 지정할 수 있습니다 (예 : sqlite3 db ".dump 'table1' 'table2'"
).
Grep을 사용하여 CREATE
줄을 제외하거나 sqlite3 $DB .dump
출력에서 INSERT
줄을 가져 오라고 제안하는 대답은 잘못 실패합니다. 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
로 바꾸십시오.
Paul Egan의 답변을 개선하면 다음과 같이 달성 할 수 있습니다.
sqlite3 database.db3 '.dump "table1" "table2"' | grep '^INSERT'
--또는--
sqlite3 database.db3 '.dump "table1" "table2"' | grep -v '^CREATE'
물론 경고는 grep을 설치해야한다는 것입니다.
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
'패널 데이터가있는 경우, 즉 ID가 많은 많은 개별 항목이 이것을 with look에 추가하고 요약 통계도 덤프합니다.
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
SQLite의 경우 명령 줄 셸 에 대한 SQLite 설명서에 따르면 "mode"를 "csv"로 설정 한 다음 SQLite 테이블 (또는 테이블의 일부)을 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"이 이미 존재합니다.
가장 좋은 방법은 스키마 부분을 제외하고 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)를 참조하십시오.
해당 쉘을 가져 와서 스키마 부분을 주석 처리하고 사용할 수도 있습니다.
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 인수를 허용하지만 이것이 충분하지 않으면 간단한 스크립트가 더 좋습니다.
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
이 버전은 인서트 내부의 개행과 잘 작동합니다.
sqlite3 database.sqlite3 .dump | grep -v '^CREATE'
실제로 줄 바꿈을 포함하지 않는 CREATE
로 시작하는 모든 줄을 제외합니다.
Retracile의 대답은 가장 가까운 대답이어야하지만 내 경우에는 효과가 없습니다. 하나의 삽입 쿼리가 중간에 중단되고 내보내기가 중단되었습니다. 이유가 무엇인지 잘 모르겠습니다. 그러나 .dump
중에는 제대로 작동합니다.
마지막으로 .dump
에서 생성 된 SQL을 분할하기위한 도구를 작성했습니다.