无法使用to\u sql将Dataframe中的数据批量插入sybase数据库表

fd3cxomn  于 2021-08-01  发布在  Java
关注(0)|答案(2)|浏览(319)

我下面代码的目的是从restful服务获取数据,对其进行规范化,用必要的列将其存储在dataframe中,最后使用pandas函数将其加载到sybase表中 to_sql .
错误:
文件“c:\program files\anaconda3\lib\site packages\sqlalchemy\engine\default.py”,第467行,在do\u executemany cursor.executemany(语句,参数)sqlalchemy.exc.programmingerror:(pyodbc.programmingerror)('42000',“[42000][sybase][odbc driver][adaptive server enterprise]附近语法不正确,'.\n(102)(sqlexecdirectw)“)[sql:'插入dbo.contract\u test(“contract\u id”,“exchange\u id”,“currency”,“trading\u code”)值(?,?,?,?)'][参数:(('0050/taiex','taiex','twd',0),('035420/kore','kore','krw',0),('0tl/lif','lif','nok',1),('100ftse/lif','lif','gbp',0),('101ftse/lif','lif'lif','gbp',0),('10stat/om','om','瑞典克朗',0),('10tb/kfx','kfx','krw',0),('10tba/kfx','kfx','krw',0)。。。显示总共4525个绑定参数集中的10个…('zurf/dtb','dtb','chf',0),('zx/nyce','nyce','usd',0))]
进程已完成,退出代码为1
代码:

from sqlalchemy.engine.url import *               
from sqlalchemy.connectors.pyodbc import *             
from sqlalchemy import create_engine                       
import urllib.request as request                  
import json                         
import pandas as pd                      
from pandas.io.json import json_normalize, DataFrame      

response = request.urlopen('http://tfsdscsw5XX/mdsclass/CONTFUTURES--O.json')            
output=response.read()                              
data=json.loads(output)           
df=json_normalize(data)                           
df1=(df[['CONTRACT_ID','EXCHANGE_ID','CURRENCY','TRADING_CODE']])                
df2=pd.DataFrame(df1)           
print(df2)                
print(df2.CONTRACT_ID)          

connector =  PyODBCConnector()                 
url = make_url("sybase+pyodbc://myhost/mydatabase?driver=Adaptive Server Enterprise&port=2306")              
print(connector.create_connect_args(url))                         
engine=create_engine(url)

# it is failing here**

df2.to_sql("contract_test",engine,index=False,if_exists="append",schema="dbo")   

response.close()

Dataframedf2中的数据示例:

CONTRACT_ID EXCHANGE_ID CURRENCY  TRADING_CODE
0      0050/TAIEX       TAIEX      TWD             0
1     035420/KORE        KORE      KRW             0
2         0TL/LIF         LIF      NOK             1
3     100FTSE/LIF         LIF      GBP             0
4     101FTSE/LIF         LIF      GBP             0

表1.2.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1

CREATE TABLE contract_test (
    CONTRACT_ID char(12) NOT NULL,
    EXCHANGE_ID char(12),
    CURRENCY char(4) NOT NULL,
    TRADING_CODE smallint
) 
GO

请帮助我们如何解决这个问题?我被困在这里了。

f4t66c6m

f4t66c6m1#

您的问题可能只是python数据库api的不兼容性。Pandas的 to_sql 真的在经营一个 executemany() 来自的呼叫 pyodbc . 此模块更常用于SQLServer,特别是在sqlalchemy的实现中。但是,与sybase的集成并不完全受支持。如sqlalchemy sybase文档页面所述:
笔记
目前不支持sqlalchemy中的sybase方言。它没有在持续集成中进行测试,可能有许多问题和警告目前没有得到处理。考虑改用外来方言。
明确地, executemany 似乎正在运行多个 VALUES sql server支持但sybase不支持的行插入(即使这两种方言都是具有已知连接历史的tsql变体):

INSERT INTO dbo.contract_test ("CONTRACT_ID", "EXCHANGE_ID", "CURRENCY", "TRADING_CODE") 
VALUES ('0050/TAIEX', 'TAIEX', 'TWD', 0), 
       ('035420/KORE', 'KORE', 'KRW', 0), 
       ('0TL/LIF', 'LIF', 'NOK', 1), 
...

相反,sybase需要具有多个 INSERT INTO 电话:

INSERT INTO dbo.contract_test ("CONTRACT_ID", "EXCHANGE_ID", "CURRENCY", "TRADING_CODE") 
VALUES ('0050/TAIEX', 'TAIEX', 'TWD', 0) 
INSERT INTO dbo.contract_test ("CONTRACT_ID", "EXCHANGE_ID", "CURRENCY", "TRADING_CODE") 
VALUES ('035420/KORE', 'KORE', 'KRW', 0)
INSERT INTO dbo.contract_test ("CONTRACT_ID", "EXCHANGE_ID", "CURRENCY", "TRADING_CODE") 
VALUES ('0TL/LIF', 'LIF', 'NOK', 1)
...

解决,而不是Pandas的方便 to_sql 方法,考虑一个直接的sqlalchemy executemany 通过使用Dataframe行列表使用参数调用 DataFrame.to_numpy() . 以下假设 contract_test 表总是预先存在的。

engine = create_engine(url)
sql = """INSERT INTO dbo.contract_test ("CONTRACT_ID", "EXCHANGE_ID", "CURRENCY", "TRADING_CODE") 
         VALUES (?, ?, ?, ?)"""

with engine.connect() as connection:
    result = connection.execute(sql, df2.to_numpy().tolist())

如果上述问题仍然存在,请集成for循环:

with engine.connect() as connection:
    for row in df2.to_numpy().tolist():
        result = connection.execute(sql, row)
bxfogqkk

bxfogqkk2#

外部sapase(sybase)方言现在是sybase推荐的sqlalchemy方言,它确实支持 fast_executemany 如果您使用sap ase odbc驱动程序。

相关问题