如何转储一些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 three
replace。
在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:
你可以在表格上进行select,在每个字段之后插入逗号来产生一个csv,或者使用一个GUI工具来返回所有的数据并保存到一个csv。