使用cursor.executemany(query,df.itertuples(index = False))进行pyodbc批量数据导入挑战

时间:2018-12-26 11:29:59

标签: python sql-server pyodbc executemany

我对python相当陌生,但是已经认真地解决了这个问题。

挑战:我想从熊猫df导入市场数据到sql表中。有大约7000种不同的股票,每个股票都有大约4000-10000的日末记录,所以我试图让pyodbc executemany正常工作,而不是更新许多代码以使用SQL Alchemy和to_sql选项。

这几行代码给我带来了很大的挑战-并要求更新SQL ODBC Driver v17以支持index = False选项。

SQL目标表:

CREATE TABLE [dbo].[EOD](
    [Exchange] [varchar](10) NOT NULL,
    [Issue] [varchar](10) NOT NULL,
    [TDate] [date] NOT NULL,
    [O] [float] NOT NULL,
    [H] [float] NOT NULL,
    [L] [float] NOT NULL,
    [C] [float] NOT NULL,
    [V] [int] NOT NULL,
    [Split] [float] NULL
) ON [PRIMARY]
GO

数据: df.head()

         date exchange issue  open  high    low  close     volume  unadj
0  2016-11-14      ASX   CGC  2.96  2.97  2.880   2.90   549167.0    0.0
1  2016-11-15      ASX   CGC  2.90  2.96  2.865   2.95   587456.0    0.0
2  2016-11-16      ASX   CGC  2.96  2.96  2.890   2.94   666295.0    0.0
3  2016-11-17      ASX   CGC  2.94  3.15  2.910   3.11  1086692.0    0.0
4  2016-11-18      ASX   CGC  3.15  3.25  3.150   3.23  2043553.0    0.0

我最接近使它起作用的方法如下。但是,这种方法会导致:

(''22007','[22007] [Microsoft] [用于SQL Server的ODBC驱动程序17] [SQL Server]从字符串转换日期和/或时间时转换失败。(241)(SQLExecDirectW)')

cursor = cnxn.cursor()
query = ("INSERT INTO [Securities].[dbo].[EOD] (Exchange, Issue, TDate, O, H, L, C, V, Split) "
         "VALUES (?,?,?,?,?,?,?,?,?) " )
try:
    cursor.executemany( query, df.itertuples(index=False) )

except Exception as e:
    print(e)
cursor.close()

pandas列已经是日期类型–因此,我不认为这是简单的日期类型转换(但无奈之下尝试了以下转换)

query = ("INSERT INTO [Securities].[dbo].[EOD] (Exchange, Issue, TDate, O, H, L, C, V, Split) "
         "VALUES (convert(date,?,126),?,?,?,?,?,?,?,?) " )

任何有关如何使这种方法有效的建议都会受到赞赏。

/ Luthor

1 个答案:

答案 0 :(得分:0)

您的DataFrame的列顺序为“日期”,“交换”,“问题”,但是INSERT语句的列顺序为“ Exchange”,“问题”,“ TDate”。因此,您显然正在尝试在“ TDate”列中插入“问题”代码('CGC')。

更改INSERT语句的列顺序以匹配DataFrame中列的顺序。