2017-09-22 45 views
1

我已经构建了一个Web UI作为ETL应用程序,允许用户选择一些包含大量记录的CSV和TSV文件,并试图将它们插入到PostgreSQL数据库中。正如已经很好地评论的那样,这个过程有点慢。经过一番研究后,它看起来像使用UNNEST函数将是我的答案,但我在实现它时遇到了麻烦。老实说,我没有像在Python中研究任何数据处理时那样找到一个很好的步骤式教程。使用unnest with psycopg2

这里的SQL字符串作为我存储他们(在功能后使用):

salesorder_write = """ 
    INSERT INTO api.salesorder (
    site, 
    sale_type, 
    sales_rep, 
    customer_number, 
    shipto_number, 
    cust_po_number, 
    fob, 
    order_number 
) VALUES (
    UNNEST(ARRAY %s) 

“””

我用这个字符串像这样的元组的列表一起:

for order in orders: 
     inputs=(
      order['site'], 
      order['sale_type'], 
      order['sales_rep'], 
      order['customer_number'], 
      order['shipto_number'], 
      order['cust_po_number'], 
      order['fob'], 
      order['order_number'] 
     ) 
     tup_list.append(inputs) 
cur.execute(strSQL,tup_list) 

这给了我错误Not all arguments converted during string formatting。我的第一个问题是如何构建我的SQL能够传递我的元组列表。我的第二个是,我可以使用现有的字典结构大致相同?

回答

1

unnest现在是不是优于(因为Psycopg 2.7)规范execute_values

from psycopg2.extras import execute_values 
orders = [ 
    dict (
     site = 'x', 
     sale_type = 'y', 
     sales_rep = 'z', 
     customer_number = 1, 
     shipto_number = 2, 
     cust_po_number = 3, 
     fob = 4, 
     order_number = 5 
    ) 
] 
salesorder_write = """ 
    insert into t (
     site, 
     sale_type, 
     sales_rep, 
     customer_number, 
     shipto_number, 
     cust_po_number, 
     fob, 
     order_number 
    ) values %s 
""" 
execute_values (
    cursor, 
    salesorder_write, 
    orders, 
    template = """(
     %(site)s, 
     %(sale_type)s, 
     %(sales_rep)s, 
     %(customer_number)s, 
     %(shipto_number)s, 
     %(cust_po_number)s, 
     %(fob)s, 
     %(order_number)s 
    )""", 
    page_size = 1000 
) 
+0

非常有趣。是否有任何基准指示性能指标? – RyanM

+0

表现明显改善,但没有我期望的那么好。我意识到我的问题可能实际上是在等待PostgreSQL服务器的响应。我正在写入一个具有自定义INSERT规则的视图,该规则又执行多个INSERT。我也将使用多线程方法进行研究。 – RyanM