【问题标题】:Python Exception No Description with Pandas read_sqlPython Exception No Description with Pandas read_sql
【发布时间】:2019-01-29 18:39:50
【问题描述】:

使用 Python,我尝试从 SQL Server 读取表,然后将数据插入 Access 中的表中。我发现最好的方法是使用 pandas 数据框。我编写了一个程序,将 SQL Server 表读入数据框,如下所示:

dataframe = pandas.read_sql(selectSql, srcConn)

它在约 209MB 的表上运行良好。当我在 ~1,116MB 表上尝试它时,它会抛出一个没有描述的异常。我猜这与它正在读取的表格的大小有关(如果它这么说会很好)。我知道 Access 只能容纳 2GB,但其中还有足够的空间,它甚至没有到达它在抛出错误之前写入 Access 的部分。

对于较大的表,有什么方法可以解决这个问题吗?有没有更好的方法我应该使用 Python 将表从 SQL Server 2008 R2 复制到 Access 2016?我在 Win10 64 位上有 16GB 的 RAM,所以这应该不是问题。我试过 32 位 Python 3.7 和 64 位 Python 3.6 无济于事。我首先尝试了 SSIS,但每当我尝试打开一个与 Access 连接的包时,它都会使我的整个 Visual Studio 崩溃。

更新:

我遵循了 Gord 在下面的建议,现在我的代码如下所示:

access_cnxn_str = (
    r'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};'
    r'DBQ=' + access_db + ';'
)
sqls_cnxn_str = (
    r'DRIVER=ODBC Driver 13 for SQL Server;'
    r'SERVER=' + sqls_server + ';'
    r'DATABASE=' + sqls_db + ';'
    r'UID=' + sqls_username + ';'
    r'PWD=' + sqls_password + ';'
)

此连接自行工作:

sqls_cnxn = pyodbc.connect(sqls_cnxn_str)

而且这个连接本身就起作用:

pyodbc.pooling = False
access_cnxn = pyodbc.connect(access_cnxn_str, autocommit = True)

但这会引发错误:

access_cnxn.execute(f"SELECT * INTO {access_table} FROM [ODBC;{sqls_cnxn_str}].{sqls_table}")

抛出的错误:

Message=('HY000', "[HY000] [Microsoft][ODBC Microsoft Access Driver] ODBC--连接到 'ODBC Driver 13 for SQL ServerSERVERNAME' 失败。 (-2001) (SQLExecDirectW)")
来源=C:\Users\bruescm\source\repos\DB_Test\DB_Test\SyncAllTests.py
StackTrace:文件 “C:\Users\bruescm\source\repos\DB_Test\DB_Test\SyncAllTests.py”,行 57,在同步表中 dest_cnxn.execute(f"SELECT * INTO {access_table} FROM [ODBC;{sqls_cnxn_str}].{sqls_table}") 文件 “C:\Users\bruescm\source\repos\DB_Test\DB_Test\SyncAllTests.py”,行 121,主要 sync_table('', sqls_table, get_access_cnxn(), access_table) 文件“C:\Users\bruescm\source\repos\DB_Test\DB_Test\SyncAllTests.py”,行 124,在 主要()

错误中的SERVERNAME 是SQL Server 所在服务器的名称。不知道为什么它与错误中的驱动程序名称相冲突。

有什么想法吗?

更新 2:

原来我的 Access 是 32 位的。这仍然无法解释为什么它无法连接,因为我最初使用的是 Python 3.7 32 位。

谢谢。

【问题讨论】:

  • 你有没有试过分批这样做,而不是一次性炸毁你的记忆
  • @aws_apprentice 我还没有尝试过批次,但如果我无法让 Gord Thompson 的答案工作,我会试一试。谢谢。
  • 在打开 Access 连接之前,请仔细检查您是否正在调用 pyodbc.pooling = False
  • @GordThompson 是的,我在建立与 Access 的连接之前设置 pyodbc.pooling = False。我的 Access 是 32 位的(即使在 64 位 Win10 机器上),我使用的是 Python 3.7 32 位。

标签: python sql-server pandas ms-access pyodbc


【解决方案1】:

我可以让 Access 数据库引擎从 SQL Server 中提取一个表,并通过简单的操作在 Access 数据库中创建一个副本

pyodbc.pooling = False  # required
cnxn = pyodbc.connect("DSN=myAccessDb", autocommit=True)
cnxn.execute("SELECT * INTO access_tbl FROM [ODBC;DSN=SQLmyDb].sql_server_tbl")

SQLmyDb 是我的 SQL Server 实例的 ODBC DSN。

更新

刚刚测试确认无 DSN 连接字符串也可以工作:

pyodbc.pooling = False  # required
access_cnxn_str = (
    r'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};'
    r'DBQ=C:\__tmp\test.accdb;'
)
cnxn = pyodbc.connect(access_cnxn_str, autocommit=True)
sql_cnxn_str = (
    r'DRIVER=ODBC Driver 17 for SQL Server;'
    r'SERVER=(local)\SQLEXPRESS;'
    r'DATABASE=myDb;'
    r'Trusted_Connection=Yes;'
)
cnxn.execute(f"SELECT * INTO access_tbl FROM [ODBC;{sql_cnxn_str}].sql_server_tbl")

【讨论】:

  • 我正在像这样初始化我的连接:conn = pyodbc.connect('Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=' + accessDb)。我应该创建一个 DSN 吗?您是否需要将 Access DB 的完整路径放在连接字符串中? DSN 是否也需要完整路径?
  • 对不起,我也在连接到没有 DSN 的 SQL Server,如下所示: 'DRIVER=SQL Server;SERVER=' + server + ';UID=' + username + ';PWD=' +密码 + ';DATABASE=' + 数据库
  • DSN 几乎不需要时间来设置,所以我建议使用它们来查看一般方法是否适合您。如果是这样,那么您可以调查是否可以使用无 DSN 连接字符串。 (我相信你可以为 Access 连接字符串,而不是嵌入式 SQL Server 连接字符串。)
  • 非常感谢@Gord Thompson!明天我回来工作时,我会试试你更新的解决方案。
  • 我尝试了使用无 DSN 连接的新解决方案,但 SELECT INTO 查询无法连接到 SQL Server。我在上面更新了我的问题。任何帮助将不胜感激!
猜你喜欢
  • 2015-09-19
  • 1970-01-01
  • 1970-01-01
  • 2020-05-01
  • 1970-01-01
  • 2014-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多