Python 使用to_sql将数据帧中的数据大容量插入Sybase数据库表失败
下面代码的目的是从restful服务中获取数据,对其进行规范化,将其存储在带有必要列的dataframe中,然后使用Pandas的Python 使用to_sql将数据帧中的数据大容量插入Sybase数据库表失败,python,sql,pandas,sqlalchemy,sybase,Python,Sql,Pandas,Sqlalchemy,Sybase,下面代码的目的是从restful服务中获取数据,对其进行规范化,将其存储在带有必要列的dataframe中,然后使用Pandas的to_sql将其加载到Sybase表中 错误: 文件“C:\Program Files\Anaconda3\lib\site packages\sqlalchemy\engine\default.py”,第467行,在do\u executemany中 cursor.executemany(语句、参数) sqlalchemy.exc.ProgrammingError:
to_sql
将其加载到Sybase表中
错误:
文件“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驱动程序][Adaptive Server Enterprise]靠近','”的语法不正确。\n(102)(SQLExecDirectW)“[SQL:'插入dbo.contract_测试(“contract_ID”,“EXCHANGE_ID”,“CURRENCY”,“TRADING_CODE”)值(?,,,,,,,?)”[parameters:('0050/TAIEX”,“TAIEX”,“TAIEX”,“TAIEX”,“TWD”,“0),('035420/KORE','KORE','KRW',0),('0TL/LIF','LIF','NOK',1),('100FTSE/LIF','LIF','GBP',0),('101FTSE/LIF','LIF','GBP',0),('10TB/KFX','KFX','0),('10TBA/KFX','KFX','KRW 0)…显示4525个总绑定参数集中的10个…('ZURF/DTB','CHF','0),('ZX/NYCE),'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()
数据帧df2中的数据示例:
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
表2.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
请帮助我如何解决这个问题?我被困在这里。您的问题可能只是Python数据库API的不兼容。Pandas的
to_sql
实际上运行的是executemany()
从pyodbc
调用。此模块更常用于SQL Server,尤其是在使用SQLAlchemy的实现中。但是,不完全支持与Sybase的集成。如SQLAlchemy Sybase中所述:
注意
SQLAlchemy中的Sybase方言当前不受支持。它是
未在持续集成中进行测试,可能有很多
目前未处理的问题和警告。请考虑使用外部设备。
而是方言
具体而言,executemany
似乎正在运行多个值
行插入,这在SQL Server中受支持,但在Sybase中不受支持(尽管这两种方言都是具有已知连接历史的TSQL变体):
插入dbo.contract\u测试(“合同ID”、“交易所ID”、“货币”、“交易代码”)
值('0050/TAIEX','TAIEX','TWD',0),
('035420/KORE','KORE','KRW',0),
('0TL/LIF','LIF','NOK',1),
...
相反,Sybase需要具有多个插入到调用的经典ANSI-SQL:
插入dbo.contract\u测试(“合同ID”、“交易所ID”、“货币”、“交易代码”)
值('0050/TAIEX','TAIEX','TWD',0)
插入dbo.contract\u测试(“合同ID”、“交易所ID”、“货币”、“交易代码”)
值('035420/KORE','KORE','KRW',0)
插入dbo.contract\u测试(“合同ID”、“交易所ID”、“货币”、“交易代码”)
值('0TL/LIF','LIF','NOK',1)
...
解决,而不是大熊猫的方便<代码> toSQL SQL <代码>方法,考虑一个直接的SqLalCyy <代码> ExtUpEngEng/Engult>使用数据帧行列表的参数调用。下面假设CurrTracyTest>表总是预先存在。
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)
您的问题可能只是Python数据库API的不兼容。Pandas的到_sql
实际上运行的是executemany()
从pyodbc
调用。此模块更常用于SQL Server,尤其是在使用SQLAlchemy的实现中。但是,不完全支持与Sybase的集成。如SQLAlchemy Sybase中所述:
注意
SQLAlchemy中的Sybase方言当前不受支持。它是
未在持续集成中进行测试,可能有很多
目前未处理的问题和警告。请考虑使用外部设备。
而是方言
具体而言,executemany
似乎正在运行多个值
行插入,这在SQL Server中受支持,但在Sybase中不受支持(尽管这两种方言都是具有已知连接历史的TSQL变体):
插入dbo.contract\u测试(“合同ID”、“交易所ID”、“货币”、“交易代码”)
值('0050/TAIEX','TAIEX','TWD',0),
('035420/KORE','KORE','KRW',0),
('0TL/LIF','LIF','NOK',1),
...
相反,Sybase需要具有多个插入到调用的经典ANSI-SQL:
插入dbo.contract\u测试(“合同ID”、“交易所ID”、“货币”、“交易代码”)
值('0050/TAIEX','TAIEX','TWD',0)
插入dbo.contract\u测试(“合同ID”、“交易所ID”、“货币”、“交易代码”)
值('035420/KORE','KORE','KRW',0)
插入dbo.contract\u测试(“合同ID”、“交易所ID”、“货币”、“交易代码”)
值('0TL/LIF','LIF','NOK',1)
...
解决,而不是大熊猫的方便<代码> toSQL SQL <代码>方法,考虑一个直接的SqLalCyy <代码> ExtUpEngEng/Engult>使用数据帧行列表的参数调用。下面假设CurrTracyTest>表总是预先存在。
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)
现在是Sybase推荐的SQLAlchemy方言,如果您使用SAP ASE ODBC驱动程序,它确实支持fast\u executemany
。现在是Sybase推荐的SQLAlchemy方言,如果您使用SAP ASE ODBC驱动程序,它确实支持fast\u executemany
。我使用了上面建议的代码,但下面的错误是:result=connection.ExecuteMay(sql,row)AttributeError:“connection”对象没有属性“ExecuteMay”进程,退出代码为1Try,运行时使用execute
。请参见编辑。文档表明DB-API将通过参数(iterables的列表/元组或单个iterable)进行检测何时使用executemany
。它现在与execute一起工作,