【问题标题】:Sharing cx_Oracle cursor between threads or processes在线程或进程之间共享 cx_Oracle 游标
【发布时间】:2019-03-01 13:13:49
【问题描述】:

我在 Oracle 中有一个数据库。我需要导出一些数据,处理它们并将数据保存到文件中。表中是 oracle sdo_geom,我需要将几何图形转换为 WKT format。几何体真的很大,一个有数千个顶点的大多边形。我正在使用SDO_UTIL.TO_WKTGEOMETRY() 函数,但它需要的时间太长。在这种情况下,选择(转换几何)到数据库是一个瓶颈。

我想到了 Python 中的 multihreadingmultiprocessing。场景应该是这样的:

  1. 创建与数据库的连接
  2. 创建 cx_Oracle.cursor
  3. 然后启动多个线程或进程共享游标
  4. 在每个线程(或进程)中,我将分块从数据库(同一张表)中选择数据
  5. 然后将所有数据发送到负责处理数据并保存到文件的线程或进程中

我通过块使用fetchmany() 选择数据:

def get_row_chunks(self):
    while True:
        rows = self.cursor.fetchmany()
        if not rows:
            break
        yield rows

所以我的问题是,是否有可能使用多线程或多处理以及如何解决这个问题(使用cx_Oracle)或psycopg2 用于PostgreSQL 我认为没关系。我认为光标在这些库中具有相同的行为。或者不可能在线程或进程之间轻松共享游标。

可能的解决方案是在数据库中预生成 WKT 几何,但在我看来这看起来更通用。

【问题讨论】:

    标签: python multithreading multiprocessing psycopg2 cx-oracle


    【解决方案1】:

    您不能同时对 cx_Oracle 中的游标或连接执行多个操作。因此,例如,您不能同时进行提取。如果您尝试这样做,您会发现 fetches 阻塞。因此,我建议您只需在一个线程中执行提取并将提取的数据传递给另一个或多个线程进行处理。

    另一种可能性是创建一个池,它允许您创建多个连接并在多个线程中使用它们(创建池时使用 threaded=True 参数)。然后,您可以使用每个连接来查询数据的不同部分。

    【讨论】:

    • 好的,但是您的建议对我没有帮助,因为问题在于 SDO_UTIL.TO_WKTGEOMETRY 函数的性能。由于此功能,获取速度太慢。我可以获取数据,然后非常快速地处理它们,我的处理线程将再次等待获取其他数据块。可以是创建更多连接的解决方案,例如仅共享 ROWNUM 或类似的东西,它告诉连接中的新游标应该在哪里获取表的新块?但我不确定它的性能,因为创建新连接很昂贵。
    • 您可以使用一个池来创建多个连接。从池中获取连接非常快。是的,如果数据库性能是瓶颈,您将不得不这样做。
    • 是的,非常感谢。我今天尝试使用线程与 ThreadPoolExecutor 进行新连接,我将尝试连接池以获得更好的性能。您可以更改/修改您的答案,我会接受答案
    • 按要求调整答案。
    猜你喜欢
    • 2011-01-20
    • 2012-03-19
    • 1970-01-01
    • 1970-01-01
    • 2013-08-20
    • 1970-01-01
    • 1970-01-01
    • 2015-11-19
    • 1970-01-01
    相关资源
    最近更新 更多