【问题标题】:How to use named binds with bulk inserts (executemany) in cx_Oracle from pandas dataframe如何在来自 pandas 数据帧的 cx_Oracle 中使用命名绑定和批量插入(executemany)
【发布时间】:2023-03-13 12:29:01
【问题描述】:

当源数据位于 Pandas Dataframe 中时,我不确定如何使用命名绑定变量从 Python 3 批量插入到 Oracle。下面的代码显示了我的尝试。使用未命名的绑定,这很容易,但容易出错,因为绑定的顺序需要与 Dataframe 中的列相同。

    "Named pandas binds with cursor.executemany in cx_oracle, how ?"
    import pandas as pd
    import cx_Oracle
    # create table t( a number, b varchar2 (20 char));
    df = pd.DataFrame(data={'a': [1, 2], 'b': ["Dog", "Cat"]})
    conn = cx_Oracle.connect('/@DB')
    cur = conn.cursor()
    # Bulk insert, numbered binds work
    cur.execute("truncate table t")
    cur.executemany("insert into t (a, b) values (:1, :2)", df.values.tolist())
    print(pd.read_sql("select a, b from t", con=conn))
    # Insert, named binds work
    cur.execute("truncate table t")
    cur.execute("insert into t (a, b) values (:cc, :dd)", dd="Donkey", cc=1)
    print(pd.read_sql("select a, b from t", con=conn))
    # Bulk insert, named binds do not work
    cur.execute("truncate table t")
    cur.executemany("insert into t (a, b) values (:cc, :dd)", dd=df['b'].values.tolist(), cc=df['a'].values.tolist())
    # TypeError: Required argument 'parameters' (pos 2) not found
    print(pd.read_sql("select a, b from t", con=conn))
    #
    conn.commit()
    cur.close()
    conn.close()

尼尔斯

【问题讨论】:

    标签: python-3.x pandas dataframe cx-oracle


    【解决方案1】:

    如果您打算使用命名绑定变量,则需要执行以下操作:

    [{"a" : 1, "b" : "Dog"}, {"a" : 2, "b" : "Cat"}]
    

    换句话说,您需要创建一个字典列表而不是列表列表。

    【讨论】:

      【解决方案2】:

      安东尼当然是对的。以下代码(根据我的原始问题修改)演示了这一点。请注意,命名绑定变量 :b, :a 与数据框中的列的顺序相反,并且即使如此匹配(这说明了我想要命名绑定的主要原因,这是为了防止依赖绑定的顺序和数据框列相同)

      谢谢。

      """
      Named cx_Oracle bind variables with cursor.executemany and pandas dataframe as input
      The trick is to convert the dataframe to a list of dictionaries
      """
      import pandas as pd
      import cx_Oracle
      # create table t(a number, b varchar2 (20 char));
      df = pd.DataFrame(data={'a': [1, 2], 'b': ["Dog", "Cat"]})
      print(df.to_dict('records'))
      conn = cx_Oracle.connect('/@DB')
      cur = conn.cursor()
      cur.executemany("insert into t (b, a) values (:b, :a)", df.to_dict('records'))
      print(pd.read_sql("select a, b from t", con=conn))
      conn.rollback()
      cur.close()
      conn.close()
      # Output
      #[{'a': 1, 'b': 'Dog'}, {'a': 2, 'b': 'Cat'}]
      #   A    B
      # 0  1  Dog
      # 1  2  Cat
      

      【讨论】:

        猜你喜欢
        • 2021-07-17
        • 2019-10-17
        • 2015-11-06
        • 2019-05-02
        • 2021-03-03
        • 2014-05-03
        • 2018-08-05
        • 2020-10-21
        • 1970-01-01
        相关资源
        最近更新 更多