我如何转储数据,只有数据,而不是模式,数据库的一些SQLite3表(不是所有表)? 转储应该是SQL格式的,因为它以后可以很容易地重新输入到数据库中,并且应该从命令行完成。就像< / p >
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)
src/shell.c:838
您甚至可以取下外壳并注释掉模式部分并使用它。
你还没说你想怎么处理被丢弃的文件。
获取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;
不是最好的方法,但至少不需要外部工具(除了grep,它是*nix盒子上的标准)
sqlite3 database.db3 .dump | grep '^INSERT INTO "tablename"'
但是您确实需要为您正在寻找的每个表执行这个命令。
注意,这不包括模式。
您可以为.dump特殊命令指定一个或多个表参数,例如__abc0。
你可以获取.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文件将只包含没有模式的数据,就像这样:
data.sql
BEGIN TRANSACTION; INSERT INTO "table1" VALUES ...; ... INSERT INTO "table2" VALUES ...; ... COMMIT;
我希望这对你有所帮助。
作为对Paul Egan的回答的改进,这可以实现如下:
sqlite3 database.db3 '.dump "table1" "table2"' | grep '^INSERT'
——或
sqlite3 database.db3 '.dump "table1" "table2"' | grep -v '^CREATE'
当然,需要注意的是必须安装grep。
这个版本在插入的换行中工作得很好:
sqlite3 database.sqlite3 .dump | grep -v '^CREATE'
实际上排除了以CREATE开头的所有行,这样不太可能包含换行符
CREATE
任何建议使用grep排除CREATE行或仅从sqlite3 $DB .dump输出中获取INSERT行的答案都将严重失败。CREATE TABLE命令每行列出一列(因此排除CREATE将无法得到全部),并且INSERT行上的值可以有嵌入的换行符(因此不能只抓取INSERT行)。
sqlite3 $DB .dump
INSERT
CREATE TABLE
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替换它。
$(sqlite $DB .tables | grep -v -e one -e two -e three)
one two three
在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的独立条目将this添加到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
伸缩的答案应该是最接近的一个,但它并不适用于我的情况。一个插入查询中途中断,导出就停止了。不知道是什么原因。然而,它在.dump期间工作正常。
.dump
最后,我写了一个工具来分解.dump生成的SQL:
https://github.com/motherapp/sqlite_sql_parser/
只包含插入
容易实现,但如果您的任何列包含新行,它将失败
SQLite插入模式
这是一个很好的可定制的解决方案,但如果你的列在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
根据命令行Shell For 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”已经存在。