Answers:
您并不是说要对转储的文件做什么。
我将使用以下内容获取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;
您可以这样做来获得.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;
我希望这可以帮助你。
sqlite3 some.db < data.sql
sqlite3 storage/db/jobs.s3db .schema jobs > schema.sql
不起作用,但echo '.schema' jobs | sqlite3 storage/db/jobs.s3db > schema.sql
可以正常工作
);
,并且grep删除了所有包含的行。向grep );
添加-x
选项可解决此问题。
这不是最好的方法,但是至少不需要外部工具(grep除外,反正这在* nix盒上是标准的)
sqlite3 database.db3 .dump | grep '^INSERT INTO "tablename"'
但是您确实需要对要查找的每个表执行此命令。
请注意,这不包括架构。
sqlite3 Database.s3db .dump
grep -v '^CREATE'
根据其他答案之一的建议更好地使用
grep -v '^CREATE;
如果CREATE
语句中有换行符(有时会这样做),则使用将中断。IMO最好的办法是根本不自动删除这些CREATE
语句,而是手动对其进行编辑。只需使用所需的任何文本编辑器,然后搜索CREATE
并手动删除这些语句即可。只要数据库不是很大(并且由于您使用的是sqlite,我想应该注意),那么这很简单。
任何建议使用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
。
作为对保罗·伊根(Paul Egan)答案的改进,可以通过以下方式实现:
sqlite3 database.db3 '.dump "table1" "table2"' | grep '^INSERT'
- 要么 -
sqlite3 database.db3 '.dump "table1" "table2"' | grep -v '^CREATE'
注意,当然,您必须安装grep。
cat database.sql | grep '^INSERT' > database_inserts.sql
grep '^CREATE'
grep '^INSERT' < database.sql > database_inserts.sql
说cat
是多余的
cat
基本上不费分文执行,使投入产出链更加清晰。当然,您也可以编写,< database.sql grep '^INSERT' ...
但是显式管道更易于阅读。
在Python或Java或任何高级语言中,.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外观中,并且还会转储摘要统计信息:
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。桌子:
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”已存在。
仅包括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
这是一个不错的且可自定义的解决方案,但如果您的列在spacespaceite中具有blob对象(例如“ Geometry”类型),则该方法不起作用
与模式差异转储
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
此版本可与插入符内的换行符一起使用:
sqlite3 database.sqlite3 .dump | grep -v '^CREATE'
实际上,排除所有CREATE
以换行开头的行都不太可能
retracile的答案应该是最接近的答案,但它不适用于我的情况。一个插入查询刚刚在中间中断,并且导出刚刚停止。不知道是什么原因。但是,它在期间工作正常.dump
。
最后,我编写了一个工具,用于拆分从生成的SQL .dump
: