【问题标题】:Insert into SQL Db from Python从 Python 插入 SQL Db
【发布时间】:2020-11-01 21:50:51
【问题描述】:

我希望使用以下代码将 python 数据框插入到 MSSQL 表中:

conn = pyodbc.connect('Driver={ODBC Driver 17 for SQL Server};\
                       Server=esql.ecs.local;\
                       Database=drgt;\
                       Trusted_Connection=yes;')
cursor = conn.cursor()  #Create cursor


for row_count in range(0, t6.shape[0]):
    chunk = t6.iloc[row_count:row_count+1,:].values.tolist()
    tuple_of_tuples = tuple(tuple(x) for x in chunk)
    cursor.executemany("insert into DWWorking.dbo.api_Nic_Data"+"([[a],[b],[c],[d],[e],[f],\
                                                      [g],[h],[i],[j],[k],[l],[m],[n],\
                                                      [o],[p],[q],[r],[s],[t],[u],[v],\
                                                      [w],[x],[y],[z],[ab],[cd],\
                                                      [ef],[gh],[ij],[kl]])\
                                                        values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
                                                                    tuple_of_tuples)

光标已打开,我检查了该表是否存在并具有所需的列。 执行时我仍然收到以下错误:

ProgrammingError: ('SQL 包含 0 个参数标记,但提供了 33 个参数', 'HY000')

我该如何解决?

【问题讨论】:

  • 为什么不 df.to_sql() 使用 sqlalchemy 引擎?当然更简单,可能更有效。 pandas docs heresqlalchemy connstr docs here.
  • @S3DEV - 也尝试使用以下代码: t6.to_sql(api_nic_data,engine,index=False,if_exists="append",schema="dbo") 错误说名称 api_nic_data 是没有定义的。这是表名,肯定存在
  • 有趣。甚至'DWWorking.dbo.api_Nic_Data'?我会继续尝试这个,你在正确的轨道上。 TBH 我不确定 pandas 正在寻找多少表名; (我不惜一切代价避免使用 MSSQL)。但同样,你在正确的轨道上。
  • @S3DEV - 原来我在上面的代码中缺少表名的单引号。这修复了第一个错误,但现在我看到:InterfaceError: (pyodbc.InterfaceError) ('IM002', '[IM002] [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified (0) (SQLDriverConnect ); [IM002] [Microsoft][ODBC Driver Manager] Invalid connection string attribute (0)') (此错误的背景:sqlalche.me/e/rvf5
  • 很高兴有帮助。我建议提出一个新问题,并提供您用于为df.to_sql() 创建 sqlalchemy 引擎的连接字符串的(经过清理的)详细信息。

标签: python sql-server


【解决方案1】:

原始查询应使用正确的 SQL,该 SQL 不使用括号括住 INSERT INTO 列列表。此外,executemany 不应该要求任何for 循环跨数据帧行,并且可以比df.to_sql 更快。此外,表和列标识符不应使用单引号。

顺便说一句,对于更简单的多行字符串,请考虑 Python 的三引号字符串。请注意,由于 Pandas v0.24,.to_numpy.values 的推荐方法(请参阅 docs)。下面假设数据框正好包含 32 列,每列都映射到相应的表列。

sql = """INSERT INTO DWWorking.dbo.api_Nic_Data 
            ([a],[b],[c],[d],[e],[f],[g],[h],[i],[j],
             [k],[l],[m],[n],[o],[p],[q],[r],[s],[t],
             [u],[v] [w],[x],[y],[z],[ab],[cd],[ef],[gh],[ij],[kl])
         VALUES (?,?,?,?,?,?,?,?,?,?,
                 ?,?,?,?,?,?,?,?,?,?,
                 ?,?,?,?,?,?,?,?,?,?,?,?)
      """ 

cursor.executemany(sql, t6.to_numpy().tolist())

【讨论】:

    【解决方案2】:

    为以后的读者提供一个正确的答案……

    按照 cmets,使用以下内容会更直接且可能更有效:

    • 熊猫DataFrame.to_sql()函数
    • sqlalchemyengine对象

    两者的文档都可以在这里找到:

    由于这种情况的用例可能因情况而异,请参阅官方文档以获取代码示例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多