关于sql:如何转储某些SQLite3表的数据?

关于sql:如何转储某些SQLite3表的数据?

How do I dump the data of some SQLite3 tables?

我该如何转储数据库的某些SQLite3表(而非所有表)的数据,而仅转储数据,而不是模式?
转储应采用SQL格式,因为以后应轻松将其重新输入数据库并应从命令行完成。 就像是

1
sqlite3 db .dump

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


您没有说要对转储的文件做什么。

我将使用以下内容获取CSV文件,该文件可以导入几乎所有内容

1
2
3
4
5
.mode csv
-- use '.separator SOME_STRING' for something other than a comma.
.headers ON
.out file.csv
SELECT * FROM MyTable;

如果您想重新插入另一个SQLite数据库,则:

1
2
3
.mode INSERT <target_table_name>
.out file.sql
SELECT * FROM MyTable;

您可以这样做来获得.schema和.dump命令的区别。例如使用grep:

1
2
3
sqlite3 SOME.db .schema > schema.sql
sqlite3 SOME.db .dump > dump.sql
grep -vx -f schema.sql dump.sql > DATA.sql

data.sql文件将仅包含不带模式的数据,如下所示:

1
2
3
4
5
6
BEGIN TRANSACTION;
INSERT INTO"table1" VALUES ...;
...
INSERT INTO"table2" VALUES ...;
...
COMMIT;

我希望这可以帮助你。


这不是最好的方法,但至少不需要外部工具(grep除外,它始终是* nix盒上的标准配置)

1
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行)。

1
2
3
4
FOR t IN $(sqlite3 $DB .tables); do
    echo -e".mode insert $t
select * 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)答案的改进,可以按以下步骤完成:

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

- 要么 -

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

注意,当然,您必须安装grep。


在Python或Java或任何高级语言中,.dump不起作用。我们需要手动将转换编码为CSV。我举一个Python示例。其他的,例子将不胜感激:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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外观中,并且还会转储摘要统计信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
        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,只需将"模式"设置为" csv",然后运行查询以提取所需的行,即可将SQLite表(或表的一部分)导出为CSV。桌子:

1
2
3
4
5
sqlite> .header ON
sqlite> .mode csv
sqlite> .once c:/WORK/dataout.csv
sqlite> SELECT * FROM tab1;
sqlite> .exit

然后使用" .import"命令将CSV(逗号分隔值)数据导入到SQLite表中:

1
2
3
sqlite> .mode csv
sqlite> .import C:/WORK/dataout.csv tab1
sqlite> .exit

请阅读有关这两种情况的更多文档:(1)表" tab1"以前不存在,并且(2)表" tab1"已存在。


审查其他可能的解决方案

仅包括INSERT

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

易于实现,但是如果您的任何列包含新行,它将失败

SQLite插入模式

1
2
3
4
FOR t IN $(sqlite3 $DB .tables); do
    echo -e".mode insert $t
select * from $t;"

done | sqlite3 $DB > backup.sql

这是一个不错的且可自定义的解决方案,但如果您的列在spacespaceite中具有Blob对象(例如" Geometry"类型),则该方法将无效

与模式差异转储

1
2
3
sqlite3 SOME.db .schema > schema.sql
sqlite3 SOME.db .dump > dump.sql
grep -v -f schema.sql dump > DATA.sql

不知道为什么,但对我不起作用

另一个(新的)可能的解决方案

这个问题可能没有最佳答案,但对我来说有用的是grep插入,考虑到列值中的换行符是这样的:

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

要选择要转储的表,.dump允许使用LIKE参数来匹配表名,但是如果这样做还不够,则可能使用简单的脚本是更好的选择

1
2
3
4
5
6
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

或者,更详细地说明如何尊重外键并将所有转储封装在一个事务中

1
2
3
4
5
6
7
8
9
10
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表达式将失败

还原它(在已创建表的数据库中)

1
sqlite3 -bail DATABASE.db3 < /tmp/backup.sql

最好的方法是采用sqlite3 db dump可以执行的代码,不包括模式部分。

伪代码示例:

1
2
3
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并注释掉架构部分并使用它。


此版本可与插入符内的换行符一起使用:

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

实际上,排除以CREATE开头的所有行(不太可能包含换行符)


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

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

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


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


推荐阅读

    linux数据库升级命令?

    linux数据库升级命令?,系统,信息,时间,最新,网络,名字,地址,管理,简介,传播,l

    linux命令行模式登录?

    linux命令行模式登录?,系统,密码,信息,状态,情况,终端,环境,管理,电脑,位置,l

    linux退出命令模式?

    linux退出命令模式?,状态,档案,命令,环境,密码,终端,文件,模式,编辑,端口,lin

    linux命令模式加行?

    linux命令模式加行?,工作,地址,系统,命令,工具,正规,信息,时间,第一,模式,Lin

    linux命令行模式使用?

    linux命令行模式使用?,工作,地址,目录,信息,名称,系统,管理,命令,文件,标准,l

    数据库导出linux命令?

    数据库导出linux命令?,密码,数据,数据库,情况,地址,系统,工具,网上,名字,命

    linux命令与数据流?

    linux命令与数据流?,工作,地址,系统,信息,命令,目录,标准,网络,管理,常用命

    linux切换成命令模式?

    linux切换成命令模式?,密码,系统,工具,模式,命令,首页,状态,图形界面,终端,

    linux恢复数据库命令?

    linux恢复数据库命令?,工具,系统,软件,数据,盘中,密码,命令,备份,数据库,文

    linux储存命令数据?

    linux储存命令数据?,系统,工作,地址,信息,标准,命令,工具,实时,数据,分析,lin

    linux命令行模式清页?

    linux命令行模式清页?,工作,系统,命令,信息,地址,目录,内容,文件,操作,功能,l

    linux储存命令数据?

    linux储存命令数据?,系统,工作,地址,信息,标准,命令,工具,实时,数据,分析,lin

    linux进入命令行模式?

    linux进入命令行模式?,系统,地址,情况,工作,命令,终端,首页,信息,目录,界面,l

    linux命令大全数据库?

    linux命令大全数据库?,服务,系统,平台,状态,软件,通用,环境,数据,神州,地址,

    linux上数据库的命令?

    linux上数据库的命令?,服务,系统,信息,地址,命令,密码,工具,管理,数据,单位,

    linux命令dm数据库?

    linux命令dm数据库?,地址,软件,时间,设备,名字,服务,位置,名称,公司,命令,lin

    linux底线模式命令?

    linux底线模式命令?,系统,档案,密码,状态,工作,命令,模式,文件,明文,界面,lin

    linux启用命令模式?

    linux启用命令模式?,系统,密码,数字,首页,电脑,情况,终端,界面,模式,命令,安

    linux命令行模式联网?

    linux命令行模式联网?,系统,网络,地址,密码,软件,检测,信息,工具,终端,界面,l

    linux回到命令行模式?

    linux回到命令行模式?,系统,密码,状态,工具,电脑,终端,界面,环境,地方,命令,