在非Windows平台(Linux或Mac)上使用Python访问Access数据库
我想要访问一个Microsoft Access数据库里的数据。我有一些.accdb和.mdb文件,想在Python中读取它们。
根据我的研究,pyodbc这个工具只能在Windows系统上使用,但我现在是在Mac OS X上工作。我对Python还很陌生。
另一个选择是,如果我能把数据库里的数据导出成csv文件,然后再在Python中使用。
任何帮助或者建议都会非常感谢。
5 个回答
这个问题虽然有点旧,但文档上说:
最简单的安装方法是使用 pip。Windows 系统会自动下载二进制文件,但其他操作系统需要从源代码编译。
所以这应该是可行的。文档里还有一个针对 Linux 机器的示例。
http://mkleehammer.github.io/pyodbc/#connecting
不过,建议你查看一下源代码中的这一部分。
https://github.com/mkleehammer/pyodbc/blob/master/tests2/accesstests.py#L630,L636
这里展示了 MS Access 文件的连接字符串是怎样的。
我在使用pandas-access
时遇到了一些问题,这个工具在很多回答中被推荐。
很多人提到使用pyodbc的问题,主要是因为在macos上找到一个mdb驱动并不容易,也不便宜。
而且,在线工具通常要求你上传数据库,这样可能会泄露一些你不想分享的数据。
所以,我最终决定自己封装一下mdbtools,这个过程其实挺简单的。如果你也遇到类似的问题,我想分享一下,希望能对你有帮助。这个工具可以将mdb文件导出为csv、excel或sqlite,具体取决于你的需求。完整的代码和文档可以在这个链接找到。
我主要封装了以下三个命令:
mdb-tables
: 这个命令可以列出mdb文件中的所有表,使用方式是mdb-tables -d ", " MDB_FILE
mdb-export
: 这个命令可以导出csv(默认格式),也可以导出到其他格式,比如sqlite,使用方式是mdb-export -I sqlite MDB_FILE TABLE_NAME
mdb-schema
: 这个命令可以获取表的结构信息,也可以指定后端格式,比如sqlite,使用方式是mdb-schema --indexes --relations --default-values --not-null MDB_FILE -T TABLE_NAME sqlite
如果你想把一个旧的 .mdb 文件转换成 .sqlite 格式,可以试试这个网站:https://www.rebasedata.com/convert-mdb-to-sqlite-online。我跟这个网站没有任何关系,只是当我在这里找不到解决办法时,最终找到的一个选择。他们提供了一个 curl 命令:
curl -F files[]=@database.ext 'https://www.rebasedata.com/api/v1/convert?outputFormat=sqlite&errorResponse=zip' -o output.zip
"根据我的研究,pyodbc只能在Windows平台上使用"
这并不正确。主要的 pyodbc页面上说:
大多数Python版本在Windows和macOS上提供了预编译的二进制文件。如果是在其他操作系统上,使用[pip install pyodbc]会从源代码构建。
不过,确实,使用ODBC来操作Access数据库主要是在Windows上进行的。“MDB Tools”和“unixODBC”常常被提到作为在非Windows平台上处理Access数据库的方法,但根据我有限的经验,我发现它们的效果并不好(如果能用的话)。
当然,你总是可以为你的非Windows平台购买一个第三方的MS Access ODBC驱动,但如果你想要一个免费的开源解决方案,可以使用UCanAccess JDBC驱动。有两种方法可以实现这一点:JayDeBeApi和Jython。
在这两种情况下,你需要下载最新版本的UCanAccess(可以在这里下载),并将“bin.zip”文件解压到一个方便的位置,确保保留文件夹结构:
(在以下示例中,我将其解压到了~/Downloads/JDBC/UCanAccess
。)
选项1:JayDeBeApi
这是推荐的选项,因为它应该能与你现有的Python环境兼容。你可以通过pip
安装JayDeBeApi。
如果你还没有安装JRE(Java运行环境),那么你也需要安装它。(我在Ubuntu上使用了sudo apt install default-jre
。)
一旦所需的组件都准备好,你应该能够使用类似下面的代码:
import jaydebeapi
db_path = "/home/gord/test.accdb"
## check your jar file version numbers
ucanaccess_jars = [
"/home/gord/Downloads/JDBC/UCanAccess/ucanaccess-5.0.1.jar",
"/home/gord/Downloads/JDBC/UCanAccess/lib/commons-lang3-3.8.1.jar",
"/home/gord/Downloads/JDBC/UCanAccess/lib/commons-logging-1.2.jar",
"/home/gord/Downloads/JDBC/UCanAccess/lib/hsqldb-2.5.0.jar",
"/home/gord/Downloads/JDBC/UCanAccess/lib/jackcess-3.0.1.jar",
]
classpath = ":".join(ucanaccess_jars)
cnxn = jaydebeapi.connect(
"net.ucanaccess.jdbc.UcanaccessDriver",
f"jdbc:ucanaccess://{db_path};newDatabaseVersion=V2010",
["", ""],
classpath
)
crsr = cnxn.cursor()
try:
crsr.execute("DROP TABLE table1")
cnxn.commit()
except jaydebeapi.DatabaseError as de:
if "user lacks privilege or object not found: TABLE1" in str(de):
pass
else:
raise
crsr.execute("CREATE TABLE table1 (id COUNTER PRIMARY KEY, fname TEXT(50))")
cnxn.commit()
crsr.execute("INSERT INTO table1 (fname) VALUES ('Gord')")
cnxn.commit()
crsr.execute("SELECT * FROM table1")
for row in crsr.fetchall():
print(row)
crsr.close()
cnxn.close()
选项2:Jython
(注意,Jython是Python的一个独立实现,它只支持Python 2.7,并且显然不再积极开发。)
重要:以下说明适用于UCanAccess版本3.0.5或更高版本。
在...
- 安装Jython(在Ubuntu上通过
sudo apt-get install jython
)和 - 下载UCanAccess并按照上面的说明解压
我创建了一个名为“dbTest.py”的Jython脚本
from com.ziclix.python.sql import zxJDBC
jdbc_url = "jdbc:ucanaccess:///home/gord/Documents/test.accdb"
username = ""
password = ""
driver_class = "net.ucanaccess.jdbc.UcanloadDriver"
cnxn = zxJDBC.connect(jdbc_url, username, password, driver_class)
crsr = cnxn.cursor()
crsr.execute("SELECT AgentName FROM Agents")
for row in crsr.fetchall():
print row[0]
crsr.close()
cnxn.close()
并用以下的shell脚本运行它
#!/bin/bash
export CLASSPATH=.:/home/gord/Downloads/JDBC/UCanAccess/loader/ucanload.jar
jython dbTest.py
在Mac OSx和Ubuntu 18.04上,你可以使用pandas_access这个工具。
根据说明文档:
import pandas_access as mdb
db_filename = 'my_db.mdb'
# Listing the tables.
for tbl in mdb.list_tables(db_filename):
print(tbl)
# Read a small table.
df = mdb.read_table(db_filename, "MyTable")
在Ubuntu上,你可能需要运行:
sudo apt install mdbtools