【问题标题】:Bulk insert into postgres table from python从python批量插入postgres表
【发布时间】:2020-06-17 17:32:40
【问题描述】:

我想将 pandas 数据帧中的值插入/更新到 postgres 表中。 我在 postgres 表中有一个唯一的元组 (a,b)。如果元组已经存在我只想更新第三个值c,如果元组不存在我想创建一个三元组(a,b,c)。

最有效的方法是什么?我猜是某种批量插入,但我不太确定具体如何。

【问题讨论】:

  • 如果解决方案对您有效,请不要忘记将问题投票为已接受(:
  • @borisdonchev 我会的 :) 但我还没有时间测试它。谢谢你的回答。

标签: python postgresql bulkinsert


【解决方案1】:

您可以将数据框转换为 CTE https://www.postgresql.org/docs/current/queries-with.html,然后将 CTE 中的数据插入到表中。像这样的:

def convert_df_to_cte(df):
    vals = ', \n'.join([f"{tuple([f'$str${e}$str$' for e in row])}" for row in df.values])
    vals = vals.replace("'$str$", "$str$")
    vals = vals.replace("$str$'", "$str$")
    vals = vals.replace('"$str$', "$str$")
    vals = vals.replace('$str$"', "$str$")
    vals = vals.replace('$str$nan$str$', 'NULL')

    columns = ', \n'.join(df.columns)

    sql = f"""
    WITH vals AS (
        SELECT 
            {columns}
        FROM 
            (VALUES {vals}) AS t ({columns})
    )
    """
    return sql


df = pd.DataFrame([[1, 2, 3]], columns=['col_1', 'col_2', 'col_3'])

cte_sql = convert_df_to_cte(df)
sql_to_insert = f"""
{cte_sql}

INSERT INTO schema.table (col_1, col_2, col_3)
SELECT 
    col_1::integer, -- don't forget to cast to right type to avoid errors
    col_2::integer, -- don't forget to cast to right type to avoid errors
    col_3::character varying
FROM 
    vals
ON CONFLICT (col_1, col_2) DO UPDATE SET
    col_3 = excluded.col_3;
"""

run_sql(sql)

【讨论】:

  • 什么是run_sql?
  • 它与您的服务器建立连接并针对特定数据库运行 SQL。我没有定义它,因为我不知道你使用什么适配器,我的猜测是你已经构建了这样的功能
猜你喜欢
  • 2014-07-23
  • 1970-01-01
  • 1970-01-01
  • 2012-06-21
  • 1970-01-01
  • 1970-01-01
  • 2018-04-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多