从sql函数调用时,Python函数挂起

时间:2015-12-01 11:48:58

标签: python postgresql psycopg2

我的Colleauge为我写了python函数,用于将数据从服务器上的文件导入postgresql db。

  1. 他的“主要”python函数在磁盘上的python脚本中写入,并使用psycopg2。
  2. 这个“主要”函数是从包装器plpythonu函数调用的,在pg服务器上用python 2定义。
  3. 基本上它使用“COPY”将数据加载到我现有的表中。

    当我从查询窗口(pgAdmin)调用包装器plpythonu函数时,它几乎立即完成(小测试数据),并正确加载数据。 但是当我尝试从我的其他函数(plpgsql)中调用它时,它就会挂起。

    当查看pg_stat_activity时,会在那里显示COPY命令,其中state ='active'且waiting ='t'。 在python函数中,我们尝试使用set_isolation_level进行自动提交,我们也尝试了显式提交。我们还尝试了一个简单的硬编码INSERT而不是COPY,但它的行为方式相同。

    有什么我们不知道或遗忘的东西吗?我尝试在谷歌搜索类似的主题,到目前为止无济于事。

    编辑 - 添加了代码,由于显而易见的原因,一些部分被遗漏了。 首先是“主要”python脚本:

    import os
    import subprocess
    import psycopg2
    import psycopg2.extensions
    
    _DB_HOST = # left out
    _DB_NAME = # left out
    _DB_USER = # left out
    _DB_PWD  = # left out
    
    #-----------------------------------------------------------------------------------------------------------------------
    def _copyFile(cur, filePath):
        # it was tried with "COPY ... , for testing I use a simpler hardcoded insert
        cmd = "insert into etl.tmp_import_file(file_line) values('test insert from python ' || clock_timestamp());"
        # table etl.tmp_import_file exists, column file_line is varchar(100), and it works when the plpythonu function is called by itself
        cur.execute(cmd)
    
    #-----------------------------------------------------------------------------------------------------------------------
    def save_file(fileId):
        dbc = psycopg2.connect(database=_DB_NAME, user=_DB_USER, host=_DB_HOST, password=_DB_PWD)
        # dbc.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT) # didn't work either
        cur = dbc.cursor()
    
        _copyFile(cur, filePath)
        dbc.commit()
        dbc.close()
    
    #-----------------------------------------------------------------------------------------------------------------------
    if __name__ == "__main__":
        import sys
        if len(sys.argv) < 2:
            print 'Usage: save_file.py <file_id>'
            sys.exit(1)
        else:
            save_file(sys.argv[1])
            sys.exit(0)
    

    这是pg server中的“包装器”plpythonu函数:

    CREATE OR REPLACE FUNCTION etl.save_file(file_id integer)
      RETURNS integer AS
    $BODY$
    
    import sys
    sys.path.append("/path_to_the_python_script")
    
    import test_save_file as c
    
    try:
        c.save_file(file_id)
        return 0
    except:
        return -1
    
    $BODY$
      LANGUAGE plpythonu VOLATILE
      COST 100;
    ALTER FUNCTION etl.save_file(integer)
      OWNER TO postgres;
    

0 个答案:

没有答案
相关问题