【问题标题】:PyODBC and Microsoft Access: Inconsistent results from simple query [closed]PyODBC 和 Microsoft Access:简单查询的结果不一致 [关闭]
【发布时间】:2010-10-24 01:44:28
【问题描述】:

我通过 Microsoft Jet 使用 pyodbc 从 Python 程序访问 Microsoft Access 2003 数据库中的数据。

Microsoft Access 数据库来自第三方;我只是在读取数据。

我在提取所需数据方面通常都取得了成功,但我最近注意到了一些差异。

我把它归结为一个简单的查询,形式如下:

SELECT field1 FROM table WHERE field1 = 601 AND field2 = 9067

我已经混淆了字段名称和值,但实际上,没有比这更简单的了!当我在 Access 中运行查询时,它返回一条记录。

然后我通过 pyodbc 运行它,代码如下所示:

connection = pyodbc.connect(connectionString)
rows = connection.execute(queryString).fetchall()

(同样,没有比这更简单的了!)

queryString 的值是从 Access 中的工作查询中剪切和粘贴的,但它返回 no 记录。我希望它会返回相同的记录。

当我更改查询以搜索 field2 的不同值时,宾果游戏可以正常工作。它拒绝的只是一些值。

所以,请帮帮我。我接下来应该在哪里寻找来解释这种差异?如果我不能相信琐碎查询的结果,我就没有机会参与这个项目!

更新:它变得更简单了!以下查询给出了不同的数字...

从表中选择 COUNT(*)

我想这是否与某些形式的缓存和/或另一个偶尔填充数据的应用程序的不正确事务管理有关。

【问题讨论】:

  • 你应该有一个游标对象来执行查询字符串吗?然后将在游标上调用 Fetchall 以生成行。见code.google.com/p/pyodbc/wiki/Rows
  • @barrowc,很有趣。我没有注意到缺少 cursor() 调用。我确定我从某处的示例中复制了这个。我尝试将其添加回 [ rows = connection.cursor().execute(queryString).fetchall() ] 但没有任何区别 - 显然 pyodbc 比 Python DB API 规范更宽容。

标签: python ms-access odbc jet pyodbc


【解决方案1】:

你能给我们一个显示这个问题的混淆数据库吗?我从来没有经历过这种情况。至少给出表定义——任何列是浮点数还是小数?

【讨论】:

  • 我投票赞成你检查浮动的建议。好主意,但这不是问题,因为更新的版本显示没有 WHERE 子句。我正在研究如何为您从 Access 中获取表描述。
【解决方案2】:

这听起来可能很愚蠢。但是……

实际数据库和连接字符串 (DSN) 的路径是否指向相同的文件位置?

【讨论】:

  • 这是一个完全合理的建议;我真的希望它变成这样微不足道的事情!我已经仔细检查过,它们都指向同一个目录。我看到 Access 2003 感到困惑,显然打开了一个最近被删除的 MDB 文件,所以我仍然想知道这里是否发生了一些缓存或类似情况。
  • MDB 文件是否位于网络路径上,您正试图在机器上使用基于 python 的应用程序来使用它?
【解决方案3】:

您是否在使用其他 ODBC 工具(例如 Query Tool)时遇到同样的问题? 您还可以在 ODBC 连接管理器中打开 ODBC 跟踪。我无权访问 并且不知道它的sql命令是否会被跟踪,但有时它可以帮助我解决ODBC问题。

【讨论】:

  • 我刚刚安装了查询工具。我必须以不同的方式指定数据源(不是连接字符串)。我跑了“从表中选择计数(*)”。它给了我与我的 Python 代码相同的答案,以及对 Access 中相同语句的不同(较小)答案。所以,好消息,这不是我的 Python 代码或 pyodbc。坏消息:我无法信任 Access/ODBC。
  • Access 是一个非常酷的工具,但它有问题。例如,有时如果您在 SQL 中编写查询并稍后对其进行编辑,它会告诉您有已纠正的语法错误——您必须将查询复制到记事本中并返回到新的 Access sql 设计视图中。对我来说,Access 似乎并没有变得更好,只是更加混乱和复杂。
  • 此问题中是否使用了 Access?据我所知,只使用了 Jet,因此不涉及 Access QBE。
【解决方案4】:

字段是否被索引?如果是这样,则可能其中一个索引已损坏,您需要压缩 MDB 文件。如果索引 损坏,可能会导致重大问题。您可能会丢失现有的关系(如果损坏的索引是 PK),或者您可能会丢失数据。因此,您需要在执行此操作之前进行备份。如果有损坏的索引,我认为交互式 Access 压缩操作会告诉你,但如果没有,你可以查找 MSysCompactErrors 表,它会告诉你压缩期间发生了哪些错误。

这种情况很少发生,可能表明以下两种情况之一:

  1. 糟糕的应用程序设计,包括过时的 Jet 版本(Service Pack 6 之前的 Jet 4 非常容易受到这种影响,这就是我遇到的问题)。

  2. 不可靠的操作环境(网络/硬件/软件)。

当然,这个建议是一个真正的远景,但它肯定是导致不同结果的一个原因(最常见的是对损坏的索引进行 ORDER BY,你最终会得到与另一个不同的记录数订购)。

【讨论】:

  • 我会检查一下。我的第一步是检查我的 JET 版本。我正在运行 Vista Service Pack 1 附带的最新版本。(support.microsoft.com/kb/239114 是我的参考。)
【解决方案5】:

在升级到 Access 2007 和从源下载数据库的新副本之间,问题已得到解决。仍然不知道根本原因是什么,但怀疑某种形式的索引损坏。

【讨论】:

    【解决方案6】:

    我猜问题可能是您没有提交查询。 PYODBC 以 autocommit = False 开头,因此每个查询(如 select、insert、update 等)都会启动一个事务,为了生效,您必须提交。在查询后调用connection.autocommit = True 或调用cursor.execute("commit") 然后fetchall。

    【讨论】:

    • 你甚至必须提交 SELECT 语句?
    • 我不了解 Access 数据库,但如果您使用的是 SQL Server,那么 havin autocommit = False 意味着有隐式事务。 msdn.microsoft.com/en-us/library/ms188317.aspx 表示即使是 SELECT 也会启动事务。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-21
    • 2013-06-21
    相关资源
    最近更新 更多