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

我如何转储数据的数据,而不是数据库的一些SQLite3表(不是所有的表)的数据,而不是模式? 转储应该是SQL格式的,因为应该稍后重新input数据库,并且应该从命令行完成。 就像是

sqlite3 db .dump 

但是不需要转储模式并select要转储的表。

你不会说你想做的转储的文件。

我会使用以下来获得一个CSV文件,我可以导入到几乎所有的东西

 .mode csv -- use '.separator SOME_STRING' for something other than a comma. .headers on .out file.dmp 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; 

我希望这可以帮助你。

不是最好的方法,但是至less不需要外部工具(grep,它是* nix盒上的标准)

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

但是你确实需要为你正在查找的每个表执行这个命令。

请注意,这不包括架构。

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

作为保罗·伊根的回答的一个改进,可以这样做:

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

– 要么 –

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

警告,当然,你必须安装grep。

任何build议使用grep来排除CREATE行或只是从sqlite3 $DB .dump输出中获取INSERT行的sqlite3 $DB .dump都会失败。 CREATE TABLE命令每行列出一列(所以不包括CREATE将不会获得全部),并且INSERT行上的值可以embedded换行符(因此不能只抓取INSERT行)。

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

testingsqlite3版本3.6.20。

如果你想排除某些表,你可以使用$(sqlite $DB .tables | grep -v -e one -e two -e three)来筛选它们,或者如果你想得到一个特定的子集,用one two threereplace。

在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 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 

根据命令行shell的SQLite文档对于SQLite,您可以将SQLite表(或表的一部分)导出为CSV,只需将“mode”设置为“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”已经存在。

你可以使用像SQLite Administrator这样的工具。

这里有很多这样的工具。

最好的方法是采取sqlite3数据库转储将执行的代码,不包括模式部分。

伪代码示例:

 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开始的行,这些行不太可能包含换行符

审查其他可能的解决scheme

仅包含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 

这是一个很好的可自定义的解决scheme,但是如果你的列有像“几何”types的blob对象

使用模式来区分转储

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

不知道为什么,但不是为我工作

另一个(新)可能的解决scheme

可能对这个问题没有一个最好的答案,但是对我来说是一个grep插入考虑到列值的新行, 像这样的expression式

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

要select转储的表,转储允许一个LIKE参数来匹配表名,但是如果这样做不够,可能是一个简单的脚本更好的select

 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 

考虑到grepexpression式将失败,如果); 是任何列中的string

要恢复它(在已经创build表的数据库中)

 sqlite3 -bail database.db3 < /tmp/backup.sql 

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

最后,我写了一个工具来分解从.dump生成的SQL:

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

你可以在表格上进行select,在每个字段之后插入逗号来产生一个csv,或者使用一个GUI工具来返回所有的数据并保存到一个csv。