使用pymssql

时间:2017-12-21 17:03:21

标签: python sql-server pandas pymssql

我正在尝试将数据帧写入SQL Server表。我的代码:

conn = pymssql.connect(host="Dev02", database="DEVDb")
cur = conn.cursor()
query = "INSERT INTO dbo.SCORE_TABLE VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"
cur.executemany(query, df_sql)
conn.commit()
cur.close()
conn.close()

df_sql的维度为(5860, 20),即数据框中的列数与SQL Server表中的列数相同。我仍然得到以下错误:

  

ValueError:sql中的占位符多于可用的params

更新

根据其中一条评论,我尝试使用turbodbc,如下所示:

conn = turbodbc.connect(driver="{SQL Server}", server="Dev02", Database="DEVDb")
conn.use_async_io = True
cur = conn.cursor()
query = "INSERT INTO dbo.STG_CONTACTABILITY_SCORE VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
cur.executemany(query, df_sql.values)
cur.commit()
cur.close()
conn.close()

我收到以下错误:

  

ValueError:具有多个元素的数组的真值   暧昧。使用a.any()或a.all()

我不明白。这里有什么问题。我看到df_sql.values,但我发现没有错。

ndarray的第一行如下:

[nan 'DUSTIN HOPKINS' 'SOUTHEAST MISSOURI STATE UNIVERSITY' 13.0
  '5736512217' None None 'Monday' '8:00AM' '9:00AM' 'Summer' None None None
  None '2017-12-22 10:39:30.626331' 'Completed' None '1-11KUFFZ'
  'Central Time Zone']

3 个答案:

答案 0 :(得分:1)

我认为你只需要指定每个列的名称,不要忘记表必须有id字段来为数据帧索引收费:

conn = pymssql.connect(host="Dev02", database="DEVDb")
cur = conn.cursor()
query = """INSERT INTO dbo.SCORE_TABLE(index, column1, column2, ..., column20)
            VALUES (?, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, 
            %s, %s, %s, %s, %s, %s)"""
cur.executemany(query, df_sql)
conn.commit()
cur.close()
conn.close()

好的,我一直在使用pandas,我将最后一个数据框导出到csv,如:

df.to_csv('new_file_name.csv', sep=',', encoding='utf-8')

然后我只使用了pyobdcBULK INSERT Transact-SQL,如:

import pyodbc

conn = pyodbc.connect(DRIVER='{SQL Server}', Server='server_name', Database='Database_name', trusted_connection='yes')
cur = conn.cursor()

cur.execute("""BULK INSERT table_name
               FROM 'C:\\Users\\folders path\\new_file_name.csv'
               WITH
               (
                   CODEPAGE = 'ACP',
                   FIRSTROW = 2,
                   FIELDTERMINATOR = ',',
                   ROWTERMINATOR = '\n'
               )""")
conn.commit()

cur.close()
conn.close()

这是第二次向SQL Server收取15314行。我希望这会给你一个想法。

答案 1 :(得分:0)

如果我理解正确,您想使用DataFrame.to_sql()方法:

df_sql.to_sql('dbo.SCORE_TABLE', conn, index=False, if_exists='append')

答案 2 :(得分:0)

可能executemany会将ndarray来自您df.values来电的每一行视为一个项,因为值之间没有逗号分隔符。因此,占位符数量超过实际绑定值,您会收到不匹配错误。

考虑将数组转换为元组元组(或列表列表/列表元组/元组列表),然后将该对象传递给executemany

query = "INTO dbo.SCORE_TABLE VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"    
sql_data = tuple(map(tuple, df.values))

cur.executemany(query, sql_data)
cur.commit()