在非Windows平台(Linux或Mac)上使用Python访问Access数据库

26 投票
5 回答
31018 浏览
提问于 2025-04-19 03:12

我想要访问一个Microsoft Access数据库里的数据。我有一些.accdb和.mdb文件,想在Python中读取它们。

根据我的研究,pyodbc这个工具只能在Windows系统上使用,但我现在是在Mac OS X上工作。我对Python还很陌生。

另一个选择是,如果我能把数据库里的数据导出成csv文件,然后再在Python中使用。

任何帮助或者建议都会非常感谢。

5 个回答

-1

这个问题虽然有点旧,但文档上说:

最简单的安装方法是使用 pip。Windows 系统会自动下载二进制文件,但其他操作系统需要从源代码编译。

所以这应该是可行的。文档里还有一个针对 Linux 机器的示例。

http://mkleehammer.github.io/pyodbc/#connecting

不过,建议你查看一下源代码中的这一部分。

https://github.com/mkleehammer/pyodbc/blob/master/tests2/accesstests.py#L630,L636

这里展示了 MS Access 文件的连接字符串是怎样的。

0

我在使用pandas-access时遇到了一些问题,这个工具在很多回答中被推荐。

很多人提到使用pyodbc的问题,主要是因为在macos上找到一个mdb驱动并不容易,也不便宜。

而且,在线工具通常要求你上传数据库,这样可能会泄露一些你不想分享的数据。

所以,我最终决定自己封装一下mdbtools,这个过程其实挺简单的。如果你也遇到类似的问题,我想分享一下,希望能对你有帮助。这个工具可以将mdb文件导出为csv、excel或sqlite,具体取决于你的需求。完整的代码和文档可以在这个链接找到。

我主要封装了以下三个命令:

  1. mdb-tables: 这个命令可以列出mdb文件中的所有表,使用方式是 mdb-tables -d ", " MDB_FILE
  2. mdb-export: 这个命令可以导出csv(默认格式),也可以导出到其他格式,比如sqlite,使用方式是 mdb-export -I sqlite MDB_FILE TABLE_NAME
  3. mdb-schema: 这个命令可以获取表的结构信息,也可以指定后端格式,比如sqlite,使用方式是 mdb-schema --indexes --relations --default-values --not-null MDB_FILE -T TABLE_NAME sqlite
0

如果你想把一个旧的 .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

22

"根据我的研究,pyodbc只能在Windows平台上使用"

这并不正确。主要的 pyodbc页面上说:

大多数Python版本在Windows和macOS上提供了预编译的二进制文件。如果是在其他操作系统上,使用[pip install pyodbc]会从源代码构建。

不过,确实,使用ODBC来操作Access数据库主要是在Windows上进行的。“MDB Tools”和“unixODBC”常常被提到作为在非Windows平台上处理Access数据库的方法,但根据我有限的经验,我发现它们的效果并不好(如果能用的话)。

当然,你总是可以为你的非Windows平台购买一个第三方的MS Access ODBC驱动,但如果你想要一个免费的开源解决方案,可以使用UCanAccess JDBC驱动。有两种方法可以实现这一点:JayDeBeApiJython

在这两种情况下,你需要下载最新版本的UCanAccess(可以在这里下载),并将“bin.zip”文件解压到一个方便的位置,确保保留文件夹结构:

UCanAccess文件夹

(在以下示例中,我将其解压到了~/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
27

在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

撰写回答