SQLite3数据库如何合并?

时间:2018-08-14 11:34:07

标签: python database merge sqlite

我有许多要合并的SQLite3数据库文件。例如,考虑由代理脚本生成的数据库文件,如下所示:

#!/usr/bin/python
# -*- coding: utf-8 -*-
import random
import time

import folktales

agent_ID = "f67b809e-c38b-465a-9e93-665ab36668f2"

def main():
    while True:
        folktales.insert_state_dictionary_into_database_table(
            entries    = {
                         "value_1" : random.random(),
                         "agent_ID": agent_ID
                         },
            table_name = "measurements",
            filepath   = "database_1.db"
        )
        time.sleep(5)

if __name__ == "__main__":
    main()

其中一个数据库的一个表可能看起来像这样:

我想要一种通用的方式(也许是一个SQL命令)来合并所有数据库中的所有单个表(可以有多个表)。该命令必须适用于不同形式的数据库(例如,不能具有表名或字段名)。

1 个答案:

答案 0 :(得分:1)

考虑使用SQLite的ATTACH DATABASE命令来查询外部数据库,然后遍历附加数据库的每个表,以将数据附加到第一个数据库。

具体地说,下面首先打开数据库,然后将每个数据库迭代地附加到包含SQLite数据库的目录中。然后在每个数据库中,查询表名,然后循环以追加其每个内容。外循环被包装在第一个数据库连接的上下文管理器with()中,因此不需要最后运行conn.close()

library(os)
library(sqlite3)

mypath = "/path/to/sqlite/databases"

# OPEN CONNECTION TO FIRST DATABASE
with sqlite3.connect(os.path.join(mypath, "myfirst.db")) as conn:    
    cur = conn.cursor()

    # LOOP THROUGH EACH DB TO ATTACH
    for db in os.listdir(mypath):
        if db != "myfirst.db" and db.endswith(".db"):
            # PASS FULL FILE NAME AS PARAMETER
            cur.execute("ATTACH ? AS curr_db;", os.path.join(mypath, db))

            # GET ALL TABLES IN curr_db
            cur.execute("SELECT name FROM curr_db.sqlite_master WHERE type='table';")
            all_tbls = cur.fetchall()

            # LOOP THROUGH EACH TABLE
            for tbl in all_tbls:
                # APPEND DATA (ASSUMING SAME COLUMNS IN SAME POSITION)
                sql = "INSERT INTO mytable SELECT * FROM curr_db.[{}];".format(tbl[0])
                cur.execute(sql)
                conn.commit() 

            cur.execute("DETACH curr_db;")

    cur.close()

请确保为实际名称更新 mypath myfirstdb mytable 。如果所有文件都正常运行,则第一个数据库的 mytable 将在 all 数据库中的 all表中维护 all 记录。您可能需要在循环之前或之后将仅第一个数据库中的每个表手动附加到 mytable 中。