如何转储数据,只转储数据库的某些SQLite3表(不是所有表)的数据,而不是模式? 转储应该是SQL格式的,因为它应该稍后可以很容易地重新输入到数据库中,并且应该从命令行完成。像
这样的东西sqlite3 db .dump
但不转储架构并选择要转储的表。
答案 0 :(得分:205)
你没有说你想对转储文件做什么。
我会使用以下内容来获取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;
答案 1 :(得分:143)
你可以通过.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;
我希望这会对你有所帮助。
答案 2 :(得分:37)
不是最好的方法,但至少不需要外部工具(除了grep,无论如何都是* nix盒子的标准配置)
sqlite3 database.db3 .dump | grep '^INSERT INTO "tablename"'
但您确实需要为您要查找的每个表执行此命令。
请注意,这不包括架构。
答案 3 :(得分:34)
您可以为.dump特殊命令指定一个或多个表参数,例如sqlite3 db ".dump 'table1' 'table2'"
。
答案 4 :(得分:10)
任何建议使用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
。
答案 5 :(得分:8)
作为Paul Egan答案的改进,这可以通过以下方式实现:
sqlite3 database.db3 '.dump "table1" "table2"' | grep '^INSERT'
- 或 -
sqlite3 database.db3 '.dump "table1" "table2"' | grep -v '^CREATE'
当然,需要注意的是你必须安装grep。
答案 6 :(得分:6)
在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 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
答案 7 :(得分:4)
根据Command Line Shell For SQLite的SQLite文档,您可以将SQLite表(或表的一部分)导出为CSV,只需设置&#34;模式&#34;到&#34; csv&#34;然后运行查询以提取表的所需行:
sqlite> .header on
sqlite> .mode csv
sqlite> .once c:/work/dataout.csv
sqlite> SELECT * FROM tab1;
sqlite> .exit
然后使用&#34; .import&#34;命令将CSV(逗号分隔值)数据导入SQLite表:
sqlite> .mode csv
sqlite> .import C:/work/dataout.csv tab1
sqlite> .exit
请阅读有关要考虑的两种情况的进一步文件:(1)表&#34; tab1&#34;以前不存在和(2)表&#34; tab1&#34;确实存在
答案 8 :(得分:3)
最好的方法是使用sqlite3 db dump可以执行的代码,不包括模式部分。
伪代码示例:
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并注释掉架构部分并使用它。
答案 9 :(得分:3)
仅包含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
这是一个很好的可自定义的解决方案,但是如果您的列具有像“几何”这样的blob对象,它就无法工作。输入spatialite
使用架构扩展转储
sqlite3 some.db .schema > schema.sql
sqlite3 some.db .dump > dump.sql
grep -v -f schema.sql dump > data.sql
不确定原因,但不适合我
对于这个问题,可能没有最佳答案,但是对我来说一个问题就是插入,考虑到列值为expression like this
的新行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
答案 10 :(得分:2)
此版本适用于插入内的换行符:
sqlite3 database.sqlite3 .dump | grep -v '^CREATE'
在实践中,排除所有以CREATE
开头且不太可能包含换行符的行
答案 11 :(得分:0)
回溯的答案应该是最接近的答案,但它对我的情况不起作用。一个插入查询刚刚中断,导出刚刚停止。不确定是什么原因。但是它在.dump
期间工作正常。
最后,我编写了一个工具,用于拆分从.dump
生成的SQL:
答案 12 :(得分:-3)
您可以在每个字段后面插入逗号以生成csv的表上选择,或者使用GUI工具返回所有数据并将其保存到csv。