如何转储某些SQLite3表的数据?

如何转储某些SQLite3表的数据?,sql,sqlite,Sql,Sqlite,如何转储数据库中某些SQLite3表(不是所有表)的数据,而不是模式? 转储应该是SQL格式的,因为它应该很容易在以后重新输入数据库,并且应该从命令行完成。差不多 sqlite3 db .dump 但无需转储架构并选择要转储的表。您可以在表上进行选择,在每个字段后插入逗号以生成csv,或者使用GUI工具返回所有数据并将其保存到csv。最好的方法是采用sqlite3 db转储将执行的代码,不包括架构部分 伪代码示例: SELECT 'INSERT INTO ' || tableName || '

如何转储数据库中某些SQLite3表(不是所有表)的数据,而不是模式? 转储应该是SQL格式的,因为它应该很容易在以后重新输入数据库,并且应该从命令行完成。差不多

sqlite3 db .dump

但无需转储架构并选择要转储的表。

您可以在表上进行选择,在每个字段后插入逗号以生成csv,或者使用GUI工具返回所有数据并将其保存到csv。

最好的方法是采用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)


您甚至可以将该shell注释掉模式部分并使用它。

您并不是在说希望对转储的文件做什么

我将使用下面的内容来获取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;
。模式插入
.out file.sql
从MyTable中选择*;

不是最好的方法,但至少不需要外部工具(grep除外,grep是标准的on*nix框)

但是,您确实需要对正在查找的每个表执行此命令


请注意,这不包括架构。

您可以为.dump特殊命令指定一个或多个表参数,例如,
sqlite3 db.dump“table1”“table2”

您可以根据.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;

我希望这对您有所帮助。

作为对Paul Egan答案的改进,可以通过以下方式实现:

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


当然,需要注意的是,您必须安装grep

此版本适用于插入中的换行符:

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


实际上,排除所有以
CREATE
开头的行,这不太可能包含换行符任何建议使用grep排除
CREATE
行的答案,或者从
sqlite3$DB中获取
INSERT
行。dump
输出将严重失败。
CREATE TABLE
命令每行列出一列(因此排除
CREATE
不会得到所有列),而
INSERT
行上的值可以嵌入换行符(因此您不能只获取
INSERT
行)

在sqlite3版本3.6.20上测试


如果要排除某些表,可以使用
$(sqlite$DB.tables | grep-v-e one-e two-e three)
对其进行筛选,或者如果要获得特定的子集,可以使用Python或Java或任何高级语言中的
1 two three

替换该子集。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 

retracile的答案应该是最接近的,但它不适用于我的情况。一个插入查询正好在中间中断,导出刚刚停止。不知道原因是什么。但是,它在
.dump
期间工作正常

最后,我编写了一个工具,用于拆分从
.dump
生成的SQL:

审查其他可能的解决方案 仅包括插入内容

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
这是一个很好的可自定义解决方案,但如果列中有类似spatialite中“Geometry”类型的blob对象,则该解决方案不起作用

将转储与架构区分开来

sqlite3 some.db .schema > schema.sql
sqlite3 some.db .dump > dump.sql
grep -v -f schema.sql dump > data.sql
不知道为什么,但不适合我

另一个(新的)可能的解决方案 也许这个问题没有最好的答案,但对我来说,一个有效的方法是grep-the-inserts,考虑到列值中的新行具有

要选择要转储的表,
。dump
允许使用类似的参数来匹配表名,但如果这还不够,则最好使用简单的脚本

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
根据的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”已经存在

什么格式?有什么特别的,或者您只是在寻找一个可读的备份?请指定。我想转储为SQL格式,以便轻松还原。我已经在主要问题中添加了这些信息。我的目的是生成一个可以轻松地重新添加到数据库中的SQL文件。我使用了
sqlite3 Database.s3db.dump
如果这些插入的值中有换行符,这将中断。更好地使用
grep-v'^CREATE'
如另一个回答中所建议的那样使用
grep-v'^CREATECREATE
语句中有换行符(它们有时会这样做),则code>将中断。依我看,最好的办法不是自动删除
CREATE
语句,而是手动编辑它们。只要使用你想要的任何文本编辑器
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
sqlite3 -bail database.db3 < /tmp/backup.sql
sqlite> .header on
sqlite> .mode csv
sqlite> .once c:/work/dataout.csv
sqlite> SELECT * FROM tab1;
sqlite> .exit
sqlite> .mode csv
sqlite> .import C:/work/dataout.csv tab1
sqlite> .exit