在Postgres和MySQL之间自动执行数据转储和恢复

时间:2016-01-28 20:18:06

标签: python mysql postgresql database-migration

我刚刚在多个Mysql DB和Porgres DB之间设置了一个delta加载数据流。它每15分钟只复制几十Mbs。

然而,我想在紧急情况下设置一个完全加载数据的过程......

Python正在崩溃,在使用SQLachemy等时似乎不够快。

我已经读过,最好的方法是将所有内容从MySQL转储到CSV中,然后使用file_fdw将整个表加载到Postgres中。

有没有人遇到过类似的问题?如果是的话,你是怎么做的?

1 个答案:

答案 0 :(得分:1)

长话短说,ORM开销正在扼杀你的表现。

当你不操纵所涉及的对象时,最好使用几乎与纯SQL一样快的SQA核心表达式(“SQL表达式”)。

解决方案:

当然我假设您的MySQL和Postgres模型已经过精心同步(即来自MySQL对象的值不是在Postgres模型中创建对象的问题,反之亦然)。

概述:

  • 从声明性类中获取Table个对象
  • 来自一个数据库的
  • select(SQLAlchemy Expression)
  • 将行转换为dict s
  • insert进入其他数据库

或多或少:

# get tables
m_table = ItemMySQL.__table__
pg_table = ItemPG.__table__

# SQL Expression that gets a range of rows quickly
pg_q = select([pg_table]).where(
    and_(
        pg_table.c.id >= id_start,
        pg_table.c.id <= id_end,

))

# get PG DB rows
eng_pg = DBSessionPG.get_bind()
conn_pg = eng_pg.connect()
result = conn_pg.execute(pg_q)
rows_pg = result.fetchall()


for row_pg in rows_pg:
    # convert PG row object into dict
    value_d = dict(row_pg)
    # insert into MySQL
    m_table.insert().values(**value_d)

# close row proxy object and connection, else suffer leaks
result.close()
conn_pg.close()

关于表现的背景,参见接受的答案(SQA主要作者本人):

Why is SQLAlchemy insert with sqlite 25 times slower than using sqlite3 directly?

既然你似乎有Python崩溃,也许你使用的内存太多了?因此,我建议分批阅读和写行。

进一步改进可能是使用.values在一次调用中插入多行,请参阅此处:http://docs.sqlalchemy.org/en/latest/core/tutorial.html#inserts-and-updates