You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何用64位Python与ODBC驱动读取32位.mdb文件?

解决64位环境下读取32位.mdb文件并导入PostgreSQL的方案

首先得明确你遇到的核心问题:64位的Microsoft Access ACE驱动对旧版32位Jet引擎创建的.mdb文件兼容性很差,加上注册表权限限制,导致直接用64位pyodbc连接会报错。下面给你几个实用的解决方案,优先适配QGIS插件的开发需求:

方案一:32位辅助脚本 + 64位QGIS插件(最稳妥的兼容方案)

因为QGIS是64位程序,没法直接在其环境里用32位驱动,所以我们可以拆分工作:用32位Python脚本专门读取.mdb文件并输出成中间格式(比如CSV),然后64位QGIS插件调用这个脚本,再把中间数据导入PostgreSQL。

步骤:

  1. 改造你的32位脚本,让它支持命令行参数(去掉GUI选择,方便插件调用):
# 32位脚本:mdb_reader.py
import csv
import pyodbc
import sys

def read_mdb_to_csv(mdb_path, table_name, output_csv, password=""):
    DRV = '{Microsoft Access Driver (*.mdb, *.accdb)}'
    try:
        con = pyodbc.connect(f'DRIVER={DRV};DBQ={mdb_path};PWD={password}')
        cur = con.cursor()
        cur.execute(f'SELECT * FROM {table_name}')
        rows = cur.fetchall()
        # 写入CSV并包含表头
        with open(output_csv, 'w', newline='', encoding='utf-8') as f:
            writer = csv.writer(f)
            writer.writerow([col[0] for col in cur.description])  # 写入字段名
            writer.writerows(rows)
        cur.close()
        con.close()
        print(f"导出成功:{output_csv}")
    except Exception as e:
        print(f"错误:{str(e)}", file=sys.stderr)
        sys.exit(1)

if __name__ == "__main__":
    # 命令行参数格式:python mdb_reader.py <mdb路径> <表名> <输出CSV路径> [密码]
    if len(sys.argv) < 4:
        print("使用方法:python mdb_reader.py <mdb_path> <table_name> <output_csv> [password]")
        sys.exit(1)
    mdb_path = sys.argv[1]
    table_name = sys.argv[2]
    output_csv = sys.argv[3]
    password = sys.argv[4] if len(sys.argv) >=5 else ""
    read_mdb_to_csv(mdb_path, table_name, output_csv, password)
  1. 在64位QGIS插件中调用这个脚本
    用Python的subprocess模块调用32位Python解释器执行上面的脚本,读取生成的CSV后导入PostgreSQL:
# 64位QGIS插件中的代码片段
import subprocess
import csv
import psycopg2
import os

def import_mdb_to_postgres(mdb_path, table_name, pg_conn_params):
    # 临时CSV路径
    temp_csv = "temp_mdb_export.csv"
    # 32位Python的路径(可让用户在插件设置中配置,适配不同环境)
    python_32_path = r"C:\Python38-32\python.exe"
    mdb_reader_script = r"插件目录下的mdb_reader.py路径"
    
    # 调用32位脚本导出CSV
    result = subprocess.run(
        [python_32_path, mdb_reader_script, mdb_path, table_name, temp_csv, "pw"],
        capture_output=True,
        text=True
    )
    if result.returncode != 0:
        raise Exception(f"导出失败:{result.stderr}")
    
    # 读取CSV并导入PostgreSQL
    conn = psycopg2.connect(**pg_conn_params)
    cur = conn.cursor()
    
    # 根据表头生成建表语句(实际可根据数据类型优化)
    with open(temp_csv, 'r', encoding='utf-8') as f:
        reader = csv.reader(f)
        headers = next(reader)
        create_table_sql = f"CREATE TABLE IF NOT EXISTS {table_name} ({', '.join([f'{h} TEXT' for h in headers])})"
        cur.execute(create_table_sql)
        # 批量插入数据
        insert_sql = f"INSERT INTO {table_name} VALUES ({', '.join(['%s']*len(headers))})"
        cur.executemany(insert_sql, reader)
    
    conn.commit()
    cur.close()
    conn.close()
    # 清理临时文件
    os.remove(temp_csv)

这个方案完全复用你已有的32位脚本经验,且兼容所有装了32位Python和Access驱动的同事设备。

方案二:使用开源MDB Tools(无需Access驱动,跨平台)

如果不想依赖Microsoft的Access驱动,可以用MDB Tools——一个开源工具集,专门读取.mdb文件,支持64位系统,甚至跨Windows/Linux/macOS。

步骤:

  1. 安装MDB Tools:Windows可用Chocolatey安装choco install mdbtools,Linux/macOS用包管理器(比如apt install mdbtools),也可下载预编译的64位版本。
  2. 在Python中调用MDB Tools
    • 方法一:直接调用命令行工具mdb-export导出CSV:
      import subprocess
      temp_csv = "temp_export.csv"
      # 导出指定表到CSV,指定日期格式
      subprocess.run(
          ["mdb-export", "-D", "%Y-%m-%d %H:%M:%S", mdb_path, table_name],
          stdout=open(temp_csv, 'w', encoding='utf-8')
      )
      # 后续导入PostgreSQL的代码同方案一
      
    • 方法二:用Python绑定库pymdbtools直接读取:
      from pymdbtools import Mdb
      
      with Mdb(mdb_path) as mdb:
          table = mdb.table(table_name)
          headers = table.columns
          rows = list(table.rows)
          # 直接用rows数据导入PostgreSQL
      

这个方案无需安装Access驱动,兼容性更好,能直接在64位QGIS环境中运行,不用额外的32位脚本。

方案三:使用商业ODBC驱动(最省心的方案)

如果预算允许,可以用支持64位读取旧版.mdb的商业ODBC驱动,比如Easysoft ODBC-Access DriverDevart ODBC Driver for Access。这类驱动专门解决64位环境下的旧Jet格式兼容性问题,安装后你几乎可以直接复用原来的pyodbc代码。

示例代码(以Easysoft为例):

import pyodbc
DRV = '{Easysoft ODBC-Access Driver}'
con = pyodbc.connect(f'DRIVER={DRV};DBQ={mdb_path};PWD=pw')
# 后续读取和导入PostgreSQL的逻辑和你原来的代码一致

这个方案适合不想折腾代码、追求稳定的场景,但需要付费购买授权。

QGIS插件整合建议

  • 在插件中添加UI界面,让用户选择.mdb文件、配置PostgreSQL连接信息、指定目标表名等。
  • 对于方案一,可增加“32位Python路径配置”的设置项,方便不同同事适配自己的环境。
  • 可以利用QGIS自带的PostgreSQL工具(比如QgsVectorLayerQgsDataSourceUri)简化数据导入,不用自己编写psycopg2的底层代码。

内容的提问来源于stack exchange,提问作者HC Pieck

火山引擎 最新活动