Python 使用SQLObject将数据从一个sqlite数据库迁移到多个sqlite数据库
到目前为止,我们的应用程序一直使用一个SQLite数据库,其中SQLObject作为ORM。显然,在某个时刻,我们知道我们必须面对SQLite并发性问题,所以我们做到了 我们最终将当前数据库拆分为多个数据库。这意味着每个表模式保持不变,但我们将不同的表分布到多个数据库中,使表紧密耦合在一起 现在,这在新版本的应用程序的干净安装中运行得非常好,但是升级到以前版本的应用程序到新版本需要进行特殊的数据迁移,然后应用程序才能开始工作。在这种情况下,数据库迁移很简单,即将表从单个数据库移动到适当的不同数据库中 举例来说,认为这是较古老的结构: single_db.db——一个单独的dbPython 使用SQLObject将数据从一个sqlite数据库迁移到多个sqlite数据库,python,sqlite,migration,sqlobject,Python,Sqlite,Migration,Sqlobject,到目前为止,我们的应用程序一直使用一个SQLite数据库,其中SQLObject作为ORM。显然,在某个时刻,我们知道我们必须面对SQLite并发性问题,所以我们做到了 我们最终将当前数据库拆分为多个数据库。这意味着每个表模式保持不变,但我们将不同的表分布到多个数据库中,使表紧密耦合在一起 现在,这在新版本的应用程序的干净安装中运行得非常好,但是升级到以前版本的应用程序到新版本需要进行特殊的数据迁移,然后应用程序才能开始工作。在这种情况下,数据库迁移很简单,即将表从单个数据库移动到适当的不同数据
* A -- Table A
* B -- Table B
* C -- Table C
* D -- Table D
* E -- Table E
* F -- Table F
新结构:
db1.db---数据库1
- A -- Table A
- B -- Table B
- C -- Table C
- D -- Table D
db2.db---数据库2
- E -- Table E
db3.db---数据库3
- F -- Table F
当升级发生时,我们的应用程序将创建包含上述3个数据库和其中的空表的新结构。此外,包含所有表和实际数据的旧数据库single_db.db也将存在。现在,在我们的应用程序可以开始工作之前,它应该移动表,或者我应该说,将数据从旧数据库中的表复制到相应的新数据库中的相应表中
我需要为这次数据库迁移编写代码。我知道我可以使用较旧的数据库连接查询表,并使用较新的数据库连接将返回的行插入到相应的表中。我应该在这里提到的一个警告是,其中一些表可能包含大量行。也就是说,在2/3的表中,行数可以达到2-250万行
既然我在SQLite上使用SQLObject,我想问一下我是否可以使用其他SLQObject技巧,以前有人这样做过吗
谢谢你的帮助。我意识到你现在可能已经解决了这个问题,但对于任何在谷歌上搜索的人来说,我必须做的几乎与OP完全相同的事情,这是我使用的代码的核心部分(它是从我发现的东西修改而来的,但我无法再次找到它来归功于原始作者,抱歉!) 如果传递原始数据库的sqlite连接和原始数据库中表的名称,此生成器将返回可以传递的命令,以便在新数据库的sqlite对象上执行 当我这样做时,我还首先对所有表进行行计数,并在执行
INSERT
行时增加一个计数器,以便显示迁移的进度
def _iterdump(connection, table_name):
"""
Returns an iterator to dump a database table in SQL text format.
"""
cu = connection.cursor()
yield('BEGIN TRANSACTION;')
# sqlite_master table contains the SQL CREATE statements for the database.
q = """
SELECT name, type, sql
FROM sqlite_master
WHERE sql NOT NULL AND
type == 'table' AND
name == :table_name
"""
schema_res = cu.execute(q, {'table_name': table_name})
for table_name, type, sql in schema_res.fetchall():
if table_name == 'sqlite_sequence':
yield('DELETE FROM sqlite_sequence;')
elif table_name == 'sqlite_stat1':
yield('ANALYZE sqlite_master;')
elif table_name.startswith('sqlite_'):
continue
else:
yield('%s;' % sql)
# Build the insert statement for each row of the current table
res = cu.execute("PRAGMA table_info('%s')" % table_name)
column_names = [str(table_info[1]) for table_info in res.fetchall()]
q = "SELECT 'INSERT INTO \"%(tbl_name)s\" VALUES("
q += ",".join(["'||quote(" + col + ")||'" for col in column_names])
q += ")' FROM '%(tbl_name)s'"
query_res = cu.execute(q % {'tbl_name': table_name})
for row in query_res:
yield("%s;" % row[0])