Python 基于DataFrame更新SQL Server中表的某些列的最佳方法?
我在SQL Server上有一个类似这样的表,其中每一行都有一个唯一的Python 基于DataFrame更新SQL Server中表的某些列的最佳方法?,python,sql-server,pandas,Python,Sql Server,Pandas,我在SQL Server上有一个类似这样的表,其中每一行都有一个唯一的事件a和事件B组合 `Global Rules Table ID Event 1 | Event 2 | Validated as | Generated as | Generated with score 1 EA1 EB1 Rule Anti-Rule 0.01 2 EA1 EB2
事件a
和事件B
组合
`Global Rules Table
ID Event 1 | Event 2 | Validated as | Generated as | Generated with score
1 EA1 EB1 Rule Anti-Rule 0.01
2 EA1 EB2 Rule Rule 0.95
3 ... ... ... ... ...
我有另一个表,它对全局规则表
具有外键约束,称为本地规则表
我有一个熊猫数据框,看起来像这样
Event 1 | Event 2 | Validated as | Generated as | Generated with score
EA1 EB1 Rule Rule 0.85
EA1 EB2 Rule Rule 0.95
... ... ... ... ...
因为我在本地规则
和全局规则
表之间有这个外键约束,所以我不能使用df.to\u sql('Global Rules',con,if\u exists='replace')
我想根据dataframe中的值在数据库中更新的列是
生成为
,而生成为得分
,那么,根据我拥有的dataframe只更新数据库表中的这些列的最佳方法是什么呢?是否有一些现成的函数或库我不知道?我还没有找到一个库来实现这一点。我开始自己写一个,在PyPi上主持,但还没有完成
在这种情况下,针对SQL临时表的内部联接可以很好地工作。它将只更新SQL中的一个子集列,并且对于更新许多记录来说非常有效
我假设您正在使用pyodbc连接到SQL server
SQL游标
#快速将记录流式传输到临时表中
cursor.fast\u executemany=True
创建临时表
将DataFrame插入到临时表中
#仅插入键和更新的值
子集=df[['ID','Generated as','Generated with score']]
#表单SQL插入语句
columns=“,”.join(subset.columns)
值=“(“+”,“.join([“?”]*len(subset.columns))+”)”
#插入
语句=“插入[#更新_全局规则表](“+列+”)值”+值
insert=[子集中x的元组(x)值]
cursor.executemany(语句,插入)
从临时表更新主表中的值
语句=“”
更新
[全球规则表]
设置
u、 名字
从…起
[全局规则表]作为t
内连接
[#更新#u全局规则表]为u
在…上
u、 ID=t.ID;
'''
cursor.execute(语句)
放下临时桌子
它抛出一个错误pyodbc.DataError:('22003','[22003][Microsoft][ODBC驱动程序17 for SQL Server]数值超出范围(0)(SQLExecute)')。您是否必须修改某些内容以允许除id之外的所有列都使用NaN值?NaN值或任何其他缺少的值(如pd.NaT),首先需要更改为标准的Python None数据类型。您列出的错误使我认为可能存在另一个问题,尽管我尚未测试。可能是SQL中的“Generated with score”列被定义为十进制类型,但您正试图向其写入浮点。实际上,在Python中生成的小数位数比SQL列所能接受的要多,我不得不用None值替换np.nan值,这就解决了这个问题。
# assuming your DataFrame also has the ID column to perform the SQL join
statement = "CREATE TABLE [#Update_Global Rules Table] (ID BIGINT PRIMARY KEY, [Generated as] VARCHAR(200), [Generated with score] FLOAT)"
cursor.execute(statement)
cursor.execute("DROP TABLE [#Update_Global Rules Table]")