【问题标题】:Why to_sql is not working with pyodbc in pandas?为什么 to_sql 不能在 pandas 中使用 pyodbc?
【发布时间】:2019-12-10 23:23:35
【问题描述】:

我有一个 Excel 文件。我将其导入数据框并尝试使用数据更新数据库表。

import pyodbc

def get_sale_file():


    try:
            cnxn = pyodbc.connect('DRIVER=ODBC Driver 17 for SQL Server;'
                      'SERVER=' + server + ';DATABASE=' + database + ';UID=' + uname + ';PWD=' + pword,
                      autocommit=False)

        files = os.listdir(ile_path)
        df = pd.DataFrame()
        for f in files:
            if (f.endswith('.xlsx') or f.endswith('.xls')):
                df = pd.read_excel(os.path.join(sap_file_path, f))
                df.to_sql('temptable', cnxn, if_exists='replace')

        query = "UPDATE MList AS mas" + \
                " SET TTY = temp.[Territory Code] ," + \
                " Freq =temp.[Frequency Code]," + \

                " FROM temptable AS temp" + \
                " WHERE mas.SiteCode = temp.[ri a]"

当我执行上面的代码块时;我明白了

1/12/2019 10:19:45 AM  ERROR: Execution failed on sql 'SELECT name FROM sqlite_master WHERE type='table' AND name=?;': ('42S02', "[42S02] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Invalid object name 'sqlite_master'. (208) (SQLExecDirectW)")

我是否以正确的方式尝试?除了to_sql?,panads 还有其他更新mssql表的功能吗? 如何克服上述错误?

编辑 我是否必须事先创建 temptable 才能加载 datafarme?如果是这样,我的文件包含 100 列,它可能会有所不同..(除了少数列)我如何确保 pandas 仅将几列加载到 temptable?

【问题讨论】:

  • 你可以使用sqlalchemy,看看这个如何建立连接stackoverflow.com/questions/15750711/…
  • 你确定cnxn包含一些吗?...
  • 您是否尝试使用 SQL Server 驱动程序访问 sqlite 数据库?错误是说 sqlite_master 无效。如果是这样,Python 已经内置了 sqlite 支持,并且不需要使用 ODBC。
  • @GiovaniSalazar 对不起,我的错,我想我必须在将文件加载到数据框之前在数据库中创建临时表?如果是这样,我的文件包含 100 列,它可能会有所不同..(除了少数列)如何确保 pandas 仅将几列加载到 temptable 中?
  • @GiovaniSalazar 使用 urllib+sqlalchemy+pyodbc 非常感谢。您可以在此处发布您的 pastebin 答案。 urllib.parse.quote_plus 正在工作

标签: python python-3.x pandas pyodbc


【解决方案1】:

根据 pandas.DataFrame.to_sql (https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_sql.html) 的指南,连接需要连接类型 sqlalchemy.engine.Engine 或 sqlite3.Connection ,然后需要使用这样的连接更改您的代码:

import sqlalchemy
import pyodbc
cnxn = sqlalchemy.create_engine("mssql+pyodbc://<username>:<password>@<dsnname>")


df.to_sql("table_name", cnxn,if_exists='replace')

更新:使用 urllib

import urllib
import pyodbc

params = urllib.quote_plus("DRIVER={ODBC Driver 17 for SQL Server};SERVER=yourserver;DATABASE=yourdatabase ;UID=user;PWD=password")
cnxn = sqlalchemy.create_engine("mssql+pyodbc:///?odbc_connect=%s" % params)

df.to_sql("table_name", cnxn,if_exists='replace')   

【讨论】:

  • 当我切换到 sqlalchemey 获取连接参数时,我得到 ERROR: (pyodbc.InterfaceError) ('IM002', '[IM002] [unixODBC][Driver Manager]Data source name not found, and no指定的默认驱动程序 (0) (SQLDriverConnect)')(此错误的背景:sqlalche.me/e/rvf5
  • 我用的是MAC机
  • 但是你已经安装了 ODBC 吗?
  • 那我需要安装什么库?我在虚拟环境中运行 python 程序。我已经有 pyodbc inplace,它正在为另一个数据库进程工作
  • 检查此链接kite.com/python/docs/sqlalchemy.dialects.mssql.pyodbc ...如何调用 DRIVER ,使用 import urllib
【解决方案2】:

您也可以尝试其他软件包,而不是 pyodbc,例如pytds 或 adodbapi。 第一个很简单,使用 adodbapi 的连接配置看起来像

from adodbapi import adodbapi as adba

raw_config_adodbapi = f"PROVIDER=SQLOLEDB.1;Data Source={server};Initial Catalog={database};trusted_connection=no;User ID={user};Password={password};"
conn = adba.connect(raw_config_adodbapi, timeout=120, autocommit=True)

此外,pyodbc 中连接字符串中的参数似乎应该包含在 {} 中,但可能不是强制性的。

【讨论】:

  • 我认为问题是,我必须事先创建 temptable 才能加载 datafarme?如果是这样,我的文件包含 100 列,它可能会有所不同..(除了少数列)我如何确保 pandas 仅将几列加载到 temptable?
猜你喜欢
  • 2017-02-11
  • 2020-11-20
  • 2020-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多