【问题标题】:How can I merge many SQLite databases?如何合并多个 SQLite 数据库?
【发布时间】:2018-06-09 18:22:20
【问题描述】:

如果我有大量 SQLite 数据库,并且都具有相同的架构,那么将它们合并在一起以便对所有数据库执行查询的最佳方法是什么?

我知道可以使用 ATTACH 来执行此操作,但它具有 32 个和 64 个数据库的 a limit,具体取决于机器上的内存系统。

【问题讨论】:

    标签: database sqlite


    【解决方案1】:

    从 DavidM 的回答中的Nabble post 总结:

    attach 'c:\test\b.db3' as toMerge;           
    BEGIN; 
    insert into AuditRecords select * from toMerge.AuditRecords; 
    COMMIT; 
    detach toMerge;
    

    根据需要重复。

    注意:根据 mike 的评论添加了 detach toMerge;

    【讨论】:

    • 还有detach toMerge;提交之后。
    • 我想这只会合并一张表。如何一次导入多个表,同时保留它们的外键?
    • 我试过了,但附加数据库中的列由于某种原因未对齐,结果错误。因此,我必须在 INSERT 和 SELECT 语句中以相同的顺序明确地声明列名。
    • 如何处理 UNIQUE 约束并更新具有相同特定列的行?
    • @user5359531 我会用其他语言(如 python)编写一些东西来发出 SQL 命令来执行上述操作,获取 SQL,运行 SQL。
    【解决方案2】:

    这将按需进行,一天可能多次。我认为它的工作方式是http://sqlite.1065341.n5.nabble.com/Attempting-to-merge-large-databases-td39548.html,其中数据库被合并到一个大型数据库中,执行查询,然后删除大型数据库。

    【讨论】:

    • 耶,linkrot...
    【解决方案3】:

    虽然这是一个非常古老的线程,但这仍然是当今编程需求中的一个相关问题。我在这里发布这个是因为所提供的答案都不是简洁、简单和直截了当的。这是为了最终出现在此页面上的 Google 员工。图形用户界面:

    1. 下载Sqlitestudio
    2. 使用Ctrl + O 键盘快捷键添加所有数据库文件
    3. 双击每个现在加载的 db 文件来打开/激活/展开它们
    4. 有趣的部分:只需右键单击每个表并单击Copy,然后在已加载的数据库文件列表中转到目标数据库(或根据需要创建新的)并右键单击目标数据库并点击Paste

    我惊异地发现,如此艰巨的任务可以使用古老的编程技能来解决:复制和粘贴 :)

    【讨论】:

    • 我刚试了一下,它说对象已经存在并输入一个新的唯一名称?
    • 对于数百个文件来说不是一个好的解决方案......这就是我们使用编程技能的原因!
    • @GuillermoOlmedo 我回答的重点很明确,即GUI we go。我特意加入了这句话。请注意。
    【解决方案4】:

    如果您只需要执行一次此合并操作(以创建一个新的更大的数据库),您可以创建一个脚本/程序来循环您的所有 sqlite 数据库,然后将数据插入到您的主(大)数据库中。

    【讨论】:

    • 您有执行此操作的代码示例吗?
    【解决方案5】:

    迟到的答案,但您可以使用:

    #!/usr/bin/python
    
    import sys, sqlite3
    
    class sqlMerge(object):
        """Basic python script to merge data of 2 !!!IDENTICAL!!!! SQL tables"""
    
        def __init__(self, parent=None):
            super(sqlMerge, self).__init__()
    
            self.db_a = None
            self.db_b = None
    
        def loadTables(self, file_a, file_b):
            self.db_a = sqlite3.connect(file_a)
            self.db_b = sqlite3.connect(file_b)
    
            cursor_a = self.db_a.cursor()
            cursor_a.execute("SELECT name FROM sqlite_master WHERE type='table';")
    
            table_counter = 0
            print("SQL Tables available: \n===================================================\n")
            for table_item in cursor_a.fetchall():
                current_table = table_item[0]
                table_counter += 1
                print("-> " + current_table)
            print("\n===================================================\n")
    
            if table_counter == 1:
                table_to_merge = current_table
            else:
                table_to_merge = input("Table to Merge: ")
    
            return table_to_merge
    
        def merge(self, table_name):
            cursor_a = self.db_a.cursor()
            cursor_b = self.db_b.cursor()
    
            new_table_name = table_name + "_new"
    
            try:
                cursor_a.execute("CREATE TABLE IF NOT EXISTS " + new_table_name + " AS SELECT * FROM " + table_name)
                for row in cursor_b.execute("SELECT * FROM " + table_name):
                    print(row)
                    cursor_a.execute("INSERT INTO " + new_table_name + " VALUES" + str(row) +";")
    
                cursor_a.execute("DROP TABLE IF EXISTS " + table_name);
                cursor_a.execute("ALTER TABLE " + new_table_name + " RENAME TO " + table_name);
                self.db_a.commit()
    
                print("\n\nMerge Successful!\n")
    
            except sqlite3.OperationalError:
                print("ERROR!: Merge Failed")
                cursor_a.execute("DROP TABLE IF EXISTS " + new_table_name);
    
            finally:
                self.db_a.close()
                self.db_b.close()
    
            return
    
        def main(self):
            print("Please enter name of db file")
            file_name_a = input("File Name A:")
            file_name_b = input("File Name B:")
    
            table_name = self.loadTables(file_name_a, file_name_b)
            self.merge(table_name)
    
            return
    
    if __name__ == '__main__':
        app = sqlMerge()
        app.main()
    

    SRC:Tool to merge identical SQLite3 databases

    【讨论】:

    • 这是合并两个数据库还是从从属数据库全部删除并从主数据库全部插入?如果这样做,一个简单的文件副本会做同样的事情,但速度更快。关键是只合并差异......
    【解决方案6】:

    这是一个简单的 python 代码,用于合并两个数据库文件或扫描目录以查找所有数据库文件并将它们全部合并在一起(只需将其他文件中的所有数据插入找到的第一个数据库文件)。请注意,此代码只是附加具有相同架构的数据库。

    import sqlite3
    import os
    
    
    def merge_databases(db1, db2):
        con3 = sqlite3.connect(db1)
    
        con3.execute("ATTACH '" + db2 +  "' as dba")
    
        con3.execute("BEGIN")
        for row in con3.execute("SELECT * FROM dba.sqlite_master WHERE type='table'"):
            combine = "INSERT OR IGNORE INTO "+ row[1] + " SELECT * FROM dba." + row[1]
            print(combine)
            con3.execute(combine)
        con3.commit()
        con3.execute("detach database dba")
    
    
    def read_files(directory):
        fname = []
        for root,d_names,f_names in os.walk(directory):
            for f in f_names:
                c_name = os.path.join(root, f)
                filename, file_extension = os.path.splitext(c_name)
                if (file_extension == '.sqlitedb'):
                    fname.append(c_name)
    
        return fname
    
    def batch_merge(directory):
        db_files = read_files(directory)
        for db_file in db_files:
            merge_databases(db_files[0], db_file)
    
    if __name__ == '__main__':
        batch_merge('/directory/to/database/files')
    

    【讨论】:

      【解决方案7】:

      如果您已到达此提要的底部,但仍未找到解决方案,这里还有一种方法可以合并 2 个或更多 sqlite 数据库的表。

      首先尝试下载并安装DB browser for sqlite database。然后尝试在 2 个窗口中打开您的数据库并尝试通过简单地拖放表格从一个到另一个来合并它们。但问题是您一次只能拖放 一个 表,因此它并不是专门针对此答案的解决方案,但如果您的数据库可以用来节省进一步搜索的时间很小。

      【讨论】:

        【解决方案8】:

        无意冒犯,就像一个开发人员对另一个开发人员一样,恐怕您的想法似乎非常低效。 在我看来,您应该将多个表存储在同一个数据库文件中,而不是联合 SQLite 数据库。

        但是,如果我弄错了,我想您可以 ATTACH 数据库,然后使用 VIEW 来简化您的查询。或者创建一个内存表并复制所有数据(但这在性能方面甚至更差,尤其是在您拥有大型数据库的情况下)

        【讨论】:

        • 当数据库工程师处理不同的副本时,合并两个数据库很有用,以便以某些方式修改结构或内容,同时用户正在修改旧的实时版本.
        • 我很欣赏这样的反馈,但这更适合对原始问题的评论,而不是“答案”。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-31
        相关资源
        最近更新 更多