#!/usr/bin/env bash
set -eu
outdb="$1"
shift
indb0="$1"
shift
cp "$indb0" "$outdb"
for table in $(sqlite3 "$outdb" "SELECT name FROM sqlite_master WHERE type='table'"); do
echo "table: $table"
for db in "$@"; do
echo "db: $db"
sqlite3 "$outdb" "attach '$db' as 'db2'" "insert into \"$table\" select * from \"db2\".\"$table\""
done
done
#!/usr/bin/env python
import os
import argparse
import sqlite3
import shutil
parser = argparse.ArgumentParser()
parser.add_argument('out')
parser.add_argument('ins', nargs='+')
args = parser.parse_args()
shutil.copyfile(args.ins[0], args.out)
con = sqlite3.connect(args.out)
cur = con.cursor()
tables = list(map(lambda e: e[0], cur.execute("SELECT name FROM sqlite_master WHERE type='table'")))
for db2 in args.ins[1:]:
cur.execute(f"attach '{db2}' as 'db2'")
for table in tables:
cur.execute(f"insert into {table} select * from db2.{table}")
con.commit()
cur.execute("detach database db2")
8条答案
按热度按时间f87krz0w1#
从DavidM的回答中总结出Nabble post:
字符串
根据需要重复。
detach toMerge;
。*7kjnsjlb2#
虽然这是一个非常古老的主题,但在今天的编程需求中,这仍然是一个相关的问题。我在这里发布这个问题,因为还没有一个答案是简洁的,简单的,直截了当的。这是为了最终出现在这个页面上的Google员工。GUI我们去:
1.下载Sqlitestudio
1.使用
Ctrl + O
键盘快捷键添加所有数据库文件1.双击每个现在加载的数据库文件以全部打开/激活/展开它们
1.有趣的部分:只需右键单击每个表并单击
Copy
,然后转到已加载数据库文件列表中的目标数据库(或根据需要创建新数据库),右键单击目标数据库并单击Paste
我惊讶地意识到,这样一个艰巨的任务可以使用古老的编程技巧来解决,称为:复制和粘贴:)
anauzrmj3#
这里有一个简单的python代码,可以合并两个数据库文件,或者扫描一个目录以找到所有数据库文件并将它们合并在一起(只需将其他文件中的所有数据插入到找到的第一个数据库文件中)。请注意,此代码只是将数据库附加到相同的模式。
字符串
ccrfmcuu4#
回答较晚,但您可以使用:用途:
字符串
SRC:Tool to merge identical SQLite3 databases
ubbxdtey5#
如果你只需要执行一次合并操作(创建一个新的更大的数据库),你可以创建一个脚本/程序,它将循环所有的sqlite数据库,然后将数据插入到你的主(大)数据库。
wwwo4jvm6#
Bash helper自动合并每个数据库中的所有表
下面是https://stackoverflow.com/a/68526717/895245的一个简洁的Bash版本,它循环遍历给定DB中具有相同模式的所有表:
sqlite-merge-dbs
字符串
这是通过从特殊的
sqlite_master
表中提取表名来实现的。样品使用:
型
试验项目:
型
输出量:
型
一个Python版本:
型
也跳过自动递增列的Bash帮助器
如果表中有重叠的自动递增PK列,
sqlite-merge-dbs
脚本可能会意外地爆炸。下面的helper通过查看
pragma table_info
helper来决定列是否自动递增,并从合并中跳过这些列,让它们在最后重新自动递增。sqlite-merge-dbs-id
型
试验项目:
型
输出量:
型
pragma table_info
的文档位于:https://www.sqlite.org/pragma.html#pragma_table_info结果集中的列包括:“name”(其名称);“type”(数据类型,如果给定,则为"“);“notnull”(列是否可以为NULL);“dflt_value”(列的默认值);和“pk”(不属于主键的列为零,或者主键中列的从1开始的索引)。
在这个例子中,我们可以观察到:
型
其输出:
型
在脚本中,我们只是跳过了任何既是
INTEGER
又是pk的东西。一个Python版本:
型
保留外键自动增加pk
好了,这就是BOSS级别!Bash变得太麻烦了,所以我拿出了一些Python:
sqlite-merge-dbs-id-ref.py
型
该脚本假设任何
INTEGER PRIMARY KEY
也是表中唯一的pk都自动递增。这是我们需要通过的测试,其中表
t
和s
由表ref
链接起来,表ref
的外键指向这两个表:型
输出量:
型
所以现在我们看到表
t
和s
的PK和以前一样递增,但是对于ref
,发生了更复杂的事情:脚本相应地用PK递增来递增外键,所以我们正确地维护了关系。例如:
from
ref
链接4|3|-3
fromt
和4|4|-4
froms
。这些值在合并之前已经链接起来了:它将价值观从以下方面联系起来:
但是在连接表上,ID现在是4和4而不是1和2,我们已经正确地解释了这一点。
该脚本依赖于
forign_key_list
杂注来列出外键https://www.sqlite.org/pragma.html#pragma_foreign_key_list E>g.:给出:
作为参考,
table_info
给出:提供:
在Ubuntu 23.04,sqlite 3.40.1上测试。
mf98qq947#
如果您已经到达这个提要的底部,但还没有找到您的解决方案,这里也有一种方法可以合并2个或更多sqlite数据库的表。
首先尝试下载并安装DB browser for sqlite database。然后尝试在两个窗口中打开您的数据库,并尝试通过简单地将表从一个窗口拖放到另一个窗口来合并它们。但问题是,您只能拖放一个窗口。因此,它不是一个真正的解决方案,但它可以用来保存一些时间,从进一步的搜索,如果您的数据库是小了
lkaoscv78#
无意冒犯,就像一个开发人员对另一个开发人员一样,我担心你的想法似乎非常低效。在我看来,你应该在同一个数据库文件中存储多个表,而不是统一SQLite数据库。
但是如果我弄错了,我想你可以附加数据库,然后使用视图来简化查询,或者在内存中创建一个表,然后复制所有数据(但这会导致性能更差,特别是如果你有大型数据库)。