如何转储数据库的一些SQLite3表(而不是所有表)的数据,并且只转储数据,而不转储模式? 转储应该是SQL格式的,因为它以后可以很容易地重新输入到数据库中,并且应该从命令行完成。类似的
sqlite3 db .dump
但是没有转储模式和选择要转储的表。
如何转储数据库的一些SQLite3表(而不是所有表)的数据,并且只转储数据,而不转储模式? 转储应该是SQL格式的,因为它以后可以很容易地重新输入到数据库中,并且应该从命令行完成。类似的
sqlite3 db .dump
但是没有转储模式和选择要转储的表。
当前回答
审查其他可能的解决方案
只包含插入
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插入,考虑到列值中的新行,使用如下表达式
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
其他回答
您可以为.dump特殊命令指定一个或多个表参数,例如sqlite3 db "。Dump 'table1' 'table2' '”。
你还没说你想怎么处理被丢弃的文件。
获取CSV文件(可以导入到几乎所有文件中)
.mode csv
-- use '.separator SOME_STRING' for something other than a comma.
.headers on
.out file.csv
select * from MyTable;
获取一个SQL文件(可以重新插入到不同的SQLite数据库中)
.mode insert <target_table_name>
.out file.sql
select * from MyTable;
伸缩的答案应该是最接近的一个,但它并不适用于我的情况。一个插入查询中途中断,导出就停止了。不知道是什么原因。但是,它在.dump期间工作正常。
最后我写了一个工具来分解.dump生成的SQL:
https://github.com/motherapp/sqlite_sql_parser/
你可以获取.schema和.dump命令的不同。例如,使用grep:
sqlite3 some.db .schema > schema.sql
sqlite3 some.db .dump > dump.sql
grep -vx -f schema.sql dump.sql > data.sql
数据。SQL文件将只包含没有模式的数据,就像这样:
BEGIN TRANSACTION;
INSERT INTO "table1" VALUES ...;
...
INSERT INTO "table2" VALUES ...;
...
COMMIT;
审查其他可能的解决方案
只包含插入
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插入,考虑到列值中的新行,使用如下表达式
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