it-swarm-vi.tech

Làm cách nào để kết xuất dữ liệu của một số bảng SQLite3?

Làm cách nào để tôi kết xuất dữ liệu và chỉ dữ liệu chứ không phải lược đồ của một số bảng SQLite3 của cơ sở dữ liệu (không phải tất cả các bảng)? Kết xuất phải ở định dạng SQL, vì nó sẽ dễ dàng được nhập lại vào cơ sở dữ liệu sau đó và nên được thực hiện từ dòng lệnh. Cái gì đó như

sqlite3 db .dump

nhưng không bỏ lược đồ và chọn bảng nào để kết xuất.

170
pupeno

Bạn không nói những gì bạn muốn làm với tệp bị đổ.

Tôi sẽ sử dụng cách sau để nhận tệp CSV mà tôi có thể nhập vào hầu hết mọi thứ

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

Nếu bạn muốn đăng nhập lại vào cơ sở dữ liệu SQLite khác thì:

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

Bạn có thể làm điều này nhận được sự khác biệt của các lệnh .schema và .dump. ví dụ với grep:

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

data.sql tệp sẽ chỉ chứa dữ liệu mà không có lược đồ, đại loại như thế này:

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

Tôi hy vọng cái này sẽ giúp bạn.

144
jellyfish

Không phải là cách tốt nhất, nhưng khi cho thuê không cần các công cụ bên ngoài (ngoại trừ grep, dù sao cũng là tiêu chuẩn trên các hộp * nix)

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

nhưng bạn cần phải thực hiện lệnh này cho mỗi bảng bạn đang tìm kiếm.

Lưu ý rằng điều này không bao gồm lược đồ.

37
polyglot

Bạn có thể chỉ định một hoặc nhiều đối số bảng cho lệnh .dump đặc biệt, ví dụ :sqlite3 db ".dump 'table1' 'table2'".

34
Paul Egan

Bất kỳ câu trả lời nào đề xuất sử dụng grep để loại trừ các dòng CREATE hoặc chỉ lấy các dòng INSERT từ đầu ra sqlite3 $DB .dump sẽ không thành công. Các lệnh CREATE TABLE liệt kê một cột trên mỗi dòng (vì vậy loại trừ CREATE sẽ không nhận được tất cả) và các giá trị trên các dòng INSERT có thể có các dòng mới được nhúng (vì vậy bạn không thể lấy chỉ các dòng INSERT).

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

Đã thử nghiệm trên phiên bản sqlite3 3.6.20.

Nếu bạn muốn loại trừ một số bảng nhất định, bạn có thể lọc chúng bằng $(sqlite $DB .tables | grep -v -e one -e two -e three) hoặc nếu bạn muốn có một tập hợp con cụ thể thay thế bằng one two three.

10
retracile

Để cải thiện câu trả lời của Paul Egan, điều này có thể được thực hiện như sau:

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

--hoặc là--

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

Tất nhiên, hãy cẩn thận là bạn phải cài đặt grep.

8
Drew

Trong Python hoặc Java hoặc bất kỳ ngôn ngữ cấp cao nào, .dump không hoạt động. Chúng tôi cần mã hóa chuyển đổi sang CSV bằng tay. Tôi đưa ra một ví dụ Python. Những người khác, ví dụ sẽ được đánh giá cao:

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

Nếu bạn có 'dữ liệu bảng điều khiển, nói cách khác, nhiều mục riêng lẻ có id sẽ thêm dữ liệu này vào giao diện và nó cũng bỏ các thống kê tóm tắt:

        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 
6
Davoud Taghawi-Nejad

Theo tài liệu SQLite cho Command Line Shell cho SQLite bạn có thể xuất bảng SQLite (hoặc một phần của bảng) dưới dạng CSV, chỉ cần đặt "chế độ" thành "csv" và sau đó chạy truy vấn để trích xuất các hàng mong muốn của bảng:

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

Sau đó, sử dụng lệnh ".import" để nhập dữ liệu CSV (giá trị được phân tách bằng dấu phẩy) vào bảng SQLite:

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

Vui lòng đọc tài liệu hướng dẫn thêm về hai trường hợp cần xem xét: (1) Bảng "tab1" không tồn tại trước đó và (2) bảng "tab1" đã tồn tại.

4
PeterCo

Phương pháp tốt nhất sẽ là lấy mã mà kết xuất db sqlite3 sẽ làm, không bao gồm các phần lược đồ.

Mã giả ví dụ:

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

Xem: src/Shell.c:838 (cho sqlite-3.5.9) cho mã thực tế

Bạn thậm chí có thể lấy Shell đó và nhận xét các phần lược đồ và sử dụng nó.

3
harningt

Xem xét các giải pháp có thể khác

Chỉ bao gồm CHERTN

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

Dễ thực hiện nhưng sẽ thất bại nếu bất kỳ cột nào của bạn bao gồm các dòng mới

Chế độ chèn SQLite

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

Đây là một giải pháp hay và có thể tùy chỉnh, nhưng nó không hoạt động nếu các cột của bạn có các đối tượng blob như kiểu 'Hình học' trong không gian

Khác biệt kết xuất với lược đồ

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

Không chắc tại sao, nhưng không làm việc cho tôi

Một giải pháp khả thi (mới) khác

Có lẽ không có câu trả lời hay nhất cho câu hỏi này, nhưng câu trả lời phù hợp với tôi là grep các phần chèn có tính đến các dòng mới trong các giá trị cột với một biểu thức như thế này

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

Để chọn các bảng, hãy bỏ đi .dump thừa nhận một đối số THÍCH để khớp với các tên bảng, nhưng nếu điều này là không đủ thì có lẽ một kịch bản đơn giản là tùy chọn tốt hơn

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

hoặc, một cái gì đó được xây dựng để tôn trọng các khóa ngoại và đóng gói tất cả các kết xuất chỉ trong một giao dịch

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

Hãy xem xét rằng biểu thức grep sẽ thất bại nếu ); là một chuỗi có trong bất kỳ cột nào

Để khôi phục nó (trong cơ sở dữ liệu với các bảng đã được tạo)

sqlite3 -bail database.db3 < /tmp/backup.sql
3
Francisco Puga

Phiên bản này hoạt động tốt với các dòng mới bên trong chèn:

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

Trong thực tế loại trừ tất cả các dòng bắt đầu bằng CREATE ít có khả năng chứa các dòng mới

2
Elia Schito

Câu trả lời của retracile phải là câu trả lời gần nhất, nhưng nó không hoạt động đối với trường hợp của tôi. Một truy vấn chèn vừa bị hỏng ở giữa và quá trình xuất chỉ dừng lại. Không chắc lý do là gì. Tuy nhiên, nó hoạt động tốt trong .dump.

Cuối cùng tôi đã viết một công cụ để phân tách SQL được tạo từ .dump:

https://github.com/othersapp/sqlite_sql_parser/

0
Walty Yeung