일부 SQLite3 테이블의 데이터를 어떻게 덤프합니까?


183

데이터베이스의 일부 SQLite3 테이블 (모든 테이블이 아님)의 데이터는 물론 스키마가 아닌 데이터 만 덤프하는 방법은 무엇입니까? 덤프는 나중에 데이터베이스에 쉽게 다시 입력해야하며 명령 행에서 수행해야하므로 SQL 형식이어야합니다. 같은 것

sqlite3 db .dump

그러나 스키마를 덤프하지 않고 덤프 할 테이블을 선택하지 않아도됩니다.


어떤 형식으로? 특히, 또는 사람이 읽을 수있는 백업을 찾고 있습니까? 명시 해주세요.
dmckee --- 전 운영자 고양이

1
SQL 형식으로 덤프하여 쉽게 복원 할 수 있습니다. 이 정보를 주요 질문에 추가했습니다.
pupeno

답변:


214

당신은 덤프 된 파일로하고 싶은 것을 말하지 않습니다.

다음을 사용하여 거의 모든 파일로 가져올 수있는 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;

SQL 문을 사용하여 프로그래밍 방식 으로이 작업을 수행하는 방법이 있습니까? 인터프리터를 사용하여 수행하는 방법을 볼 수 있지만 스크립트를 작성하려면 어떻게해야합니까?
coleifer

4
sqlite3 db.sq3 <sample.txt
CyberFonic

" 또는 .output 대신 .once 명령을 사용하면 콘솔로 복귀하기 전에 단일 다음 명령에 대해서만 출력이 리디렉션됩니다. 표준 출력에 다시 쓰기 시작하려면 인수없이 .output을 사용하십시오. " SQLite docs
ruffin

156

.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;

이것이 도움이되기를 바랍니다.


5
@anurageldorado 일반 SQL입니다. 그냥 실행sqlite3 some.db < data.sql
해파리

일부 rasson은 나를 위해 작동하지 않습니다. 나는 주위에 사용이 필요합니다. sqlite3 storage/db/jobs.s3db .schema jobs > schema.sql하지 작동하지만 echo '.schema' jobs | sqlite3 storage/db/jobs.s3db > schema.sql잘 작동
abkrim

2
그것은 좋은 해결책처럼 보였지만 제 경우에는 대부분의 줄이 실제로 grep에 의해 제거되고 있습니다. .schema 명령은 여러 행에 각 테이블의 스키마를 생성하므로에만 포함 된 행이 );있고 grep은 grep );-x옵션 추가를 포함하는 모든 행을 제거 하여이 문제를 해결합니다.
Sunder

38

최선의 방법은 아니지만 외부 도구가 필요하지 않습니다 (어쨌든 * nix 박스의 표준 인 grep 제외)

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

그러나 찾고있는 각 테이블에 대해이 명령을 수행해야합니다.

여기에는 스키마가 포함되지 않습니다.


1
내가 사용sqlite3 Database.s3db .dump
Jader Dias

3
해당 인서트에 값에 줄 바꿈이 있으면 중단됩니다. grep -v '^CREATE'다른 답변 중 하나에서 제안한대로 더 잘 사용
dequis

1
명령문에 줄 바꿈이있는 경우 (때때로) 사용 grep -v '^CREATE;하면 중단됩니다 CREATE. 가장 좋은 IMO는 CREATE문장 을 자동으로 제거하지 않고 수동으로 편집하는 것입니다. 필요한 텍스트 편집기를 사용 CREATE하고 해당 문장을 검색 하고 수동으로 제거하십시오. 데이터베이스가 크지 않은 한 (및 sqlite를 사용하고 있기 때문에 참고 할 것입니다), 이것은 매우 간단합니다.
Dan Jones

그러나 create의 grep은 뷰에서 create를 가져옵니다. 어떻게 제거 할 수 있습니까?
Silve2611

35

.dump 특수 명령에 대해 하나 이상의 테이블 인수를 지정할 수 있습니다 (예 :) sqlite3 db ".dump 'table1' 'table2'".


4
언급 한대로 여러 테이블 이름을 추가하면 다음과 같은 결과가 나옵니다. Usage : .dump?-preserve-rowids? ? 같은 패턴?
mwm

1
@mwm에서 동일한 문제를 관찰하고 sqlite3 3.31.1 (2020/01/27)있습니다. 변경 로그는 그것에 대해 아무것도 말하지 않는다. (그건 그렇고, --preserve-rowids작업을 수행하지만, 전혀 설명되어 있지 않습니다.)
ynn

11

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.


9

Paul Egan의 답변을 개선하면 다음과 같이 달성 할 수 있습니다.

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

--또는--

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

물론 경고는 grep을 설치해야한다는 것입니다.


1
난이게 좋아. 추가 보너스로, 덤프 된 SQL 파일이 매달려 있으면 여전히 작동합니다 cat database.sql | grep '^INSERT' > database_inserts.sql(스키마와 동일, 다음으로 대체grep '^CREATE'
trisweb

2
@trisweb, 물론 당신은 grep '^INSERT' < database.sql > database_inserts.sql그것이 cat불필요한 것을 의미 합니다
Sebastian

1
그것에 대해 불필요한 것은 없습니다. 은 cat기본적으로 실행하는 비용이 들지 않으며, 입력 출력의 체인이 더 명확하게한다. 물론 작성할 수도 < database.sql grep '^INSERT' ...있지만 명시 적 파이프를 훨씬 쉽게 읽을 수 있습니다.
rjh

1
언급 한대로 여러 테이블 이름을 추가하면 다음과 같은 결과가 나옵니다. Usage : .dump?-preserve-rowids? ? 같은 패턴?
mwm

-1 : CREATE로 줄을 찾는 것은 쓸모없는 생각입니다. 주석이 포함 된 경우 특히 모든보기 또는 트리거에는 둘 이상의 행이 필요합니다.
취소

6

Python 또는 Java 또는 모든 고급 언어에서 .dump가 작동하지 않습니다. 변환을 직접 CSV로 코딩해야합니다. 나는 파이썬 예제를 제공합니다. 다른 예는 다음과 같습니다.

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 

4

명령 줄 셸에 대한 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"이 이미 존재합니다.


3

가장 좋은 방법은 스키마 부분을 제외하고 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의 경우)를 참조하십시오.

해당 쉘을 가져 와서 스키마 부분을 주석 처리하고 사용할 수도 있습니다.


3

다른 가능한 솔루션 검토

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

2

이 버전은 인서트 내부의 개행과 잘 작동합니다.

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

실제로 CREATE개행을 포함하지 않는 것으로 시작하는 모든 행을 제외합니다.


0

retracile의 대답은 가장 가까운 대답이어야하지만 내 경우에는 효과가 없습니다. 하나의 삽입 쿼리가 중간에 중단되고 내보내기가 중단되었습니다. 이유가 무엇인지 잘 모르겠습니다. 그러나 동안 잘 작동합니다 .dump.

마지막으로 다음에서 생성 된 SQL을 분할하기위한 도구를 작성했습니다 .dump.

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


-3

csv를 생성하기 위해 각 필드 뒤에 쉼표를 삽입하여 테이블을 선택하거나 GUI 도구를 사용하여 모든 데이터를 반환하고 csv에 저장할 수 있습니다.


2
내 의도는 DB에 쉽게 다시 추가 할 수있는 SQL 파일을 생성하는 것이 었습니다.
pupeno
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.