为什么在使用 iloc 操作数据帧数据后无法将数据帧值传输到 SQL Server

问题描述

我有一个 csv 文件,我将其转换为 Pandas 数据框 (df),然后操作几列中的值,最后将数据框导出到 sql Server 中的表中。

代码是:

import pyodbc
import sys

df = pd.read_csv(f'../data/polreg/{sys.argv[3]}',usecols=[0,1,2,3,4,5,8,10,11,17,18,20])

# trim leading and trailing white space from all string type columns
df_obj = df.select_dtypes(['object'])
df[df_obj.columns] = df_obj.apply(lambda x: x.str.strip())

# drop all non-alphanumeric values at end policy numbers using regex
df['a'].replace(to_replace = '[\W^]+$',value='',regex=True,inplace=True)


df.loc[df['b'] == 'rn',['b']] = None
df.loc[df['b'] == 'cn',['b']] = df['c']
df.loc[df['b'] != None,['c']] = None

#define connection string to database and create connection cursor "cur"
conn = pyodbc.connect('Driver={sql Server};'
                      f'Server={sys.argv[1]};'
                      f'Database={sys.argv[2]};'
                      'Trusted_Connection=yes;')
cur = conn.cursor()

cur.execute('EXEC src.CreateJob;') #Execute stored procedure src.CreateJob

#get most recent jobId value from src.ExtractJob,create new column in csv_df called jobId,fill all values of jobId column with jobId value.
cur.execute('SELECT TOP(1) jobId FROM src.ExtractJob ORDER BY jobId DESC;')
extractJob_info = cur.fetchall()
jobId = extractJob_info[0][0]
df["jobId"] = jobId


# execute src.Update stored procedure for each row in df
Update_query = """EXEC src.Update @a=?,@b=?,@c=?,@d=?,@e=?,@f=?,@g=?,@h=?,@i=?,@j=?,@k=?,@l=?,@jobId=?"""
for index,row in df.iterrows():
    values = (row['a'],row['b'],row['c'],row['d'],row['e'],row['f'],row['g'],row['h'],row['i'],row['j'],row['k'],row['l'],jobId)
    cur.execute(Update_query,values)

cur.execute(f'EXEC src.FinishJob @jobID = {jobId}') # execute src.FinishJob sotred procedure

cur.commit()

当我最初编写代码时,它运行良好,但后来意识到我需要操作“b”和“c”列,因此我添加了以 df.loc[...] = value ( 开头的 3 行代码)它们就在我创建连接游标之前)。当我在这 3 行代码之后检查 df 的值时,它们完全按照我的要求执行操作,因此我认为一切都已准备就绪,但是当我运行我的代码时,我收到了错误消息。

"回溯(最近一次调用最后一次): 文件“C:”第 48 行,在 cur.execute(更新查询,值) pyodbc.ProgrammingError: ('42000','[42000] [Microsoft][ODBC sql Server Driver][sql Server]传入的表格数据流 (TDS) 远程过程调用 (RPC) 协议流不正确。参数 13 ("@ b"): 提供的值不是数据类型浮点数的有效实例。检查源数据中是否有无效值。无效值的一个示例是比例大于精度的数字类型数据。(8023) (sqlExecDirectW)') "

我终生无法弄清楚导致此错误发生的数据帧中发生了什么变化。如果我取出前面提到的 3 行代码,一切正常,但是“b”和“c”列中的值显然不正确,因为我仍然需要操作它们。使用 df.loc[...] = value 是否会以某种方式改变数据帧的索引?我真的迷失在这里,任何帮助将不胜感激。

解决方法

这是老派的做法。尝试这样做。 waaayyyy 更好!

import pyodbc

engine = "mssql+pyodbc://your_server_name?driver=SQL Server Native Client 11.0?trusted_connection=yes"

# your dataframe stuff goes here...

df.to_sql(name_of_sql_table,engine,if_exists='append',index=True,index_label=['your_label')

您可以在此处找到文档。

https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_sql.html

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...