to_sql pyodbc count 字段不正确或语法错误

2023-12-15

我正在从 api 网站下载 Json 数据,并使用 sqlalchemy、pyodbc 和 pandas 的 to_sql 函数将该数据插入到 MSSQL 服务器中。

我最多可以下载 10000 行,但是我必须将块大小限制为 10,否则会出现以下错误:

DBAPIError: (pyodbc.Error) ('07002', '[07002] [Microsoft][SQL Server Native Client 11.0]COUNT 字段不正确或语法错误 (0) (SQLExecDirectW)') [SQL: '插入 [TEMP_生产实体_详细信息]

大约有 5 亿行需要下载,它只是以这个速度爬行。关于解决方法有什么建议吗?

Thanks,


在提出这个问题时,pandas 0.23.0 刚刚发布。该版本更改了默认行为.to_sql()从调用 DBAPI.executemany()构造表值构造函数 (TVC) 的方法,该构造函数通过使用单个值插入多行来提高上传速度.execute()调用 INSERT 语句。不幸的是,这种方法经常超出 T-SQL 对存储过程 2100 个参数值的限制,从而导致问题中引用的错误。

此后不久,随后发布的 pandas 添加了method=论证.to_sql()。默认值 –method=None– 恢复了之前的使用行为.executemany(),同时指定method="multi"会告诉.to_sql()使用更新的 TVC 方法。

大约在同一时间,SQLAlchemy 1.3 发布了,它添加了fast_executemany=True论证create_engine()使用 Microsoft SQL Server 的 ODBC 驱动程序,大大提高了上传速度。有了这样的增强,method=None事实证明至少和method="multi"同时避免 2100 个参数的限制。

因此,对于当前版本的 pandas、SQLAlchemy 和 pyodbc,使用的最佳方法.to_sql()与 Microsoft 的 SQL Server ODBC 驱动程序一起使用fast_executemany=True和默认行为.to_sql(), i.e.,

connection_uri = (
    "mssql+pyodbc://scott:tiger^[email protected]/db_name"
    "?driver=ODBC+Driver+17+for+SQL+Server"
)
engine = create_engine(connection_uri, fast_executemany=True)
df.to_sql("table_name", engine, index=False, if_exists="append")

对于在 Microsoft 支持其 ODBC 驱动程序的 Windows、macOS 和 Linux 变体上运行的应用程序,建议使用此方法。如果您需要使用 FreeTDS ODBC,那么.to_sql()可以调用method="multi" and chunksize=如下所述。


(原答案)

在 pandas 0.23.0 版本之前,to_sql将为 DataTable 中的每一行生成一个单独的 INSERT:

exec sp_prepexec @p1 output,N'@P1 int,@P2 nvarchar(6)',
    N'INSERT INTO df_to_sql_test (id, txt) VALUES (@P1, @P2)',
    0,N'row000'
exec sp_prepexec @p1 output,N'@P1 int,@P2 nvarchar(6)',
    N'INSERT INTO df_to_sql_test (id, txt) VALUES (@P1, @P2)',
    1,N'row001'
exec sp_prepexec @p1 output,N'@P1 int,@P2 nvarchar(6)',
    N'INSERT INTO df_to_sql_test (id, txt) VALUES (@P1, @P2)',
    2,N'row002'

大概是为了提高性能,pandas 0.23.0 现在生成一个表值构造函数来每次调用插入多行

exec sp_prepexec @p1 output,N'@P1 int,@P2 nvarchar(6),@P3 int,@P4 nvarchar(6),@P5 int,@P6 nvarchar(6)',
    N'INSERT INTO df_to_sql_test (id, txt) VALUES (@P1, @P2), (@P3, @P4), (@P5, @P6)',
    0,N'row000',1,N'row001',2,N'row002'

问题在于 SQL Server 存储过程(包括系统存储过程,例如sp_prepexec)仅限于 2100 个参数,因此如果 DataFrame 有 100 列,则to_sql一次只能插入大约20行。

我们可以计算出所需的chunksize using

# df is an existing DataFrame
#
# limit based on sp_prepexec parameter count
tsql_chunksize = 2097 // len(df.columns)
# cap at 1000 (limit for number of rows inserted by table-value constructor)
tsql_chunksize = 1000 if tsql_chunksize > 1000 else tsql_chunksize
#
df.to_sql('tablename', engine, index=False, if_exists='replace',
          method='multi', chunksize=tsql_chunksize)

然而,最快的方法仍然可能是:

  • 将 DataFrame 转储到 CSV 文件(或类似文件),然后

  • 让 Python 调用 SQL Serverbcp将该文件上传到表中的实用程序。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

to_sql pyodbc count 字段不正确或语法错误 的相关文章

随机推荐

  • SQL Server 中按 x 排序,然后按 y 列排序

    考虑一个像这样的表 debit credit code 0 10 5 5 0 3 0 11 2 0 15 1 7 0 6 6 0 2 5 0 1 我需要生成这样的结果集 首先借记 然后按代码列排序 debit credit code 5 0
  • 如何在 Flutter 中更改主题?

    所以我在这里尝试获取当前主题 无论是浅色还是深色 所以我可以相应地改变小部件颜色 但是 它不起作用 我使用 if 语句来知道何时是黑暗模式 但它总是 False 这是代码 顺便说一句 它在深色和浅色主题之间切换 但是当我尝试获取当前主题时
  • Subversion E160004 X的根节点的前身是Y但应该是Z

    我继承了一个大型 Subversion 存储库 74010 修订版 并且我正在尝试执行转储 加载以将存储库升级到 1 8 版本 以利用节省空间的功能 在尝试这个过程之前我跑了svnadmin verify对有问题的存储库进行检查 以确保该存
  • 在 Google 商店中将多个 Chrome 扩展程序作为单个项目发布

    Chrome 扩展程序和 Chrome 应用程序具有我需要实现某些功能的 API 但我无法仅使用扩展程序或仅使用应用程序或使用本机代码来实现此目的 所以我制作了一个扩展程序和一个应用程序 并使它们通过消息相互通信 一切正常 但现在我必须发布
  • 将表单提交到操作 php 文件

    我有一个表单 当用户单击 提交 时 我需要运行一个 php 文件 下面是表单和 php 文件
  • Spirit X3,如何让属性类型匹配规则类型?

    对于 Spirit X3 解析器的开发 我想使用语义操作 脚注 1 对我来说 控制如何将属性存储到 STL 容器中非常重要 这个问题是关于如何控制解析器属性 attr ctx 与规则类型 val ctx 匹配 以便可以正确分配它 也许这个问
  • 如何构建电影数据库和用户选择?

    我想创建电影数据库 用户可以在其中标记他 她观看和喜欢的电影 class Movies ndb Model watched ndb UserProperty liked ndb UserProperty 那行得通吗 我使用谷歌帐户 以后我应
  • PySpark - RDD 中对象的时间重叠

    我的目标是根据时间重叠对对象进行分组 我的每个对象rdd包含一个start time and end time 我可能效率很低 但我计划做的是根据每个对象是否与任何其他对象有任何时间重叠来为每个对象分配一个重叠 id 我有时间重叠的逻辑 然
  • 为什么Spring Boot时找不到bean?

    我以更方便的方式重新配置了 DAO 通过使用 JpaRepository 而不是手动执行所有样板代码 但现在每次我启动 Spring 应用程序时都会出现以下错误 APPLICATION FAILED TO START Description
  • React-Redux 和 Connect - 为什么我的状态在点击时没有更新?

    我是 redux 的新手 正在编写一个简单的投票前端 允许用户对他们最喜欢的框架 Angular React Vue 进行投票 当用户点击他们想要投票的框架时 我打算将商店中的投票增加一票 我在用着combineReducers and c
  • 多个条件Where子句

    我目前有一个查询 它将根据任何内容从我的数据库中提取大量信息where我想使用的条件 declare CaseNum char 7 ImportId char FormatId char SessionId char 5 set CaseN
  • 从文件共享运行 .NET 应用程序,无需代码签名

    每当从文件共享运行 NET exe 时 NET 安全模型都会引发安全错误 从本地驱动器运行时不会出现该错误 有谁知道无需签署代码即可解决此问题的方法吗 使用 CasPol 完全信任共享 更多答案在这里 为什么我的 NET 应用程序在从网络驱
  • Windows Azure 中的持续集成服务器

    我想在我的项目中使用持续集成系统 但是 我不想使用办公室中的服务器 而是希望我的持续集成服务器在 Windows Azure 上运行 有人设置过这个吗 是否有在 Azure 中托管 Hudson 或 CruiseControl Net 或任
  • 传递给函数时指向结构的指针根本不改变

    stack h define MAX STACK 10 typedef int STACK ITEM typedef struct Stack STACK stack c include stack h struct Stack STACK
  • Firebase 根视图控制器未找到警告

    我今天收到来自 Firebase Analytics 的奇怪警告 这是
  • mysql 具有多个变量的表结构

    我正在编写一个脚本 它将根据不同的条件计算票数并将计数存储在汇总表中 我无法理解如何构建我的表 因为会有超过 1 个变量 该脚本将每周运行一次 每次执行都会添加新的一周 一旦新的月份开始并且脚本执行 就会添加新的月份 一旦新年开始 就会添加
  • 将 r 中的列转换为行[重复]

    这个问题在这里已经有答案了 我使用代码形成了以下数据 test lt data frame dis c 10 20 30 40 dur c 30 40 60 90 method c car car Bicycle Bicycle to lo
  • 我可以为多个 mysql 命令行调用输入一次密码,而查询事先并不知道吗?

    您可以通过将查询放入文件来避免重新输入 mysql 命令行密码 就我而言 直到第一个查询完成后才确定后面的查询 这种情况发生在非交互式脚本中 因此运行 mysql 控制台不是一个选项 mysql 命令行交互有会话的概念吗 或者我可以将其设置
  • 如何按月分组并在特定月份没有值时返回零?

    这是我的mysql收入表 id title description date amount 1 Vehicle sales up From new sale up 2016 09 09 9999 99 2 Jem 2 Sales From
  • to_sql pyodbc count 字段不正确或语法错误

    我正在从 api 网站下载 Json 数据 并使用 sqlalchemy pyodbc 和 pandas 的 to sql 函数将该数据插入到 MSSQL 服务器中 我最多可以下载 10000 行 但是我必须将块大小限制为 10 否则会出现