我在一个管理非常糟糕的遗留Paradox数据库系统的环境中工作。(我不是管理员。)我一直在使用pyodbc与我们的表进行交互,基本功能似乎可以工作。以下是一些(工作)测试代码:
import pyodbc
LOCATION = "C:test"
cnxn = pyodbc.connect(r"Driver={{Microsoft Paradox Driver (*.db )}};DriverID=538;Fil=Paradox 5.X;DefaultDir={0};Dbq={0};CollatingSequence=ASCII;".format(LOCATION), autocommit=True, readonly=True)
cursor = cnxn.cursor()
cursor.execute("select last, first from test")
row = cursor.fetchone()
print row
问题是,我们大多数重要的表几乎在任何时候都会在某人的Paradox GUI中打开。每当我试图从其中一个表中执行select
时,我都会收到这个错误:
pyodbc.Error: ('HY000', "[HY000] [Microsoft][ODBC Paradox Driver] Could not lock
table 'test'; currently in use by user '(unknown)' on machine '(unknown)'. (-1304)
(SQLExecDirectW)")
很明显,这是因为pyodbc在调用cursor.execute()
时试图锁定表。这种行为非常合理,因为cursor.execute()
运行任意的SQL代码,可以更改表。
然而,Paradox本身(通过其gui)似乎可以很好地处理多个用户。它只会给你类似的错误,如果你试图重组表,而人们正在使用它
有没有什么方法可以让pyodbc使用某种只读模式,这样当我只执行select
之类的操作时,它就不必锁定表了?还是锁定是它工作的一个基本部分,我将无法绕过它?
使用其他模块的解决方案也完全可以。
好吧,我终于想通了。
显然,odbc不喜欢没有主键的Paradox表。在任何情况下都不能更新没有主键的表,也不能从没有主键的表格中读取,除非您是唯一试图访问该表格的用户。
如果不提供密码,则会从受密码保护的表中收到基本相同的错误消息。
所以我在两个不同的表上测试我的脚本,其中一个表同时有密码和主键,另一个表两者都没有。我认为错误消息有相同的根本原因,但实际上是两个不同的问题,有不同的解决方案。
如果表在某人的GUI中打开,似乎仍然无法访问没有主键的表,但这是一个较小的问题。
确保您在这里有最新版本的pyobdc
(3.0.6),根据他们的说法,他们
添加了Cursor.commit()和Cursor.rollback()。现在可以使用只在代码中使用光标,而不是跟踪连接和一个光标。
添加了要连接的只读关键字。如果设置为True,则SQLSetConnectAttrSQL_ATTR_ACCESS_MODE设置为SQL_MODE_READ_ONLY。这可以提供更好的锁定语义或某些驱动程序的速度。
修复了读取长度超过4K的SQL Server XML数据类型时出错的问题。
此外,我已经在使用readonly
的paradox服务器上测试了这一点,它确实有效。
希望这能有所帮助!
我刚刚发布了一个Python库,用于通过pxlib C库读取Paradox数据库文件:https://github.com/mherrmann/pypxlib.这是在文件级别操作的,因此也应该允许您独立于当前访问数据库的其他人来读取数据库。由于它不同步读/写访问,因此您必须小心!