如何使用 pyodbc 将表从 MS Access 迁移到 Postgres?
Posted
技术标签:
【中文标题】如何使用 pyodbc 将表从 MS Access 迁移到 Postgres?【英文标题】:How to use pyodbc to migrate tables from MS Access to Postgres? 【发布时间】:2021-03-13 14:50:44 【问题描述】:我需要将表从 MS Access 迁移到 Postgres。我想使用 pyodbc 来执行此操作,因为它允许我使用 python 连接到 Access 数据库并查询数据。
我的问题是我不完全确定如何以编程方式创建具有相同架构的表,而不仅仅是使用字符串格式创建 SQL 语句。 pyodbc 提供了列出所有字段、字段类型和字段长度的功能,因此我可以创建一个包含所有相关信息的长 SQL 语句,但是如何为一堆表执行此操作?我需要为每个表构建 SQL 字符串语句吗?
import pyodbc
access_conn_str = (r'DRIVER=Microsoft Access Driver (*.mdb, *.accdb); 'r'DBQ=C:\Users\bob\access_database.accdb;')
access_conn = pyodbc.connect(access_conn_str)
access_cursor = access_conn.cursor()
postgres_conn_str = ("DRIVER=PostgreSQL Unicode;""DATABASE=access_database;""UID=user;""PWD=password;""SERVER=localhost;""PORT=5433;")
postgres_conn = pyodbc.connect(postgres_conn_str)
postgres_cursor = postgres_conn.cursor()
table_ditc =
row_dict =
for row in access_cursor.columns(table='table1'):
row_dict[row.column_name] = [row.type_name, row.column_size]
table_ditc['table1'] = row_dict
for table, values in table_ditc.items():
print(f"Creating table for table")
access_cursor.execute(f'SELECT * FROM table')
result = access_cursor.fetchall()
postgres_cursor.execute(f'''CREATE TABLE table (Do I just put a bunch of string formatting in here?);''')
postgres_cursor.executemany(f'INSERT INTO table (Do I just put a bunch of string formatting) VALUES (string formatting?)', result)
postgres_conn.commit()
如您所见,对于 pyodbc,我不确定如何构建 SQL 语句。我知道我可以手动构建一个长字符串,但是如果我正在做一堆不同的表,不同的字段等,那将是不现实的。有没有更好、更简单的方法来根据 Access 数据库的架构创建表和插入行?
【问题讨论】:
您是否曾四处寻找可能为您处理繁重工作的现有工具?可能是this 之类的东西? @GordThompson 不,我没有研究过其他工具。你的建议看起来很不错,我去看看。 MDB-tools。示例:mdb-schema -T some_table some_db.mdb postgres
@AdrianKlaver 我试了一下 MDB-tools。当我使用此命令mdb-schema access_database.accdb postgres | tr 'A-Z' 'a-z' | psql -d postgres_database -U postgres -W -h 192.168.0.242 -p 5433
导出表时,它会创建所有表,但最后我得到两个错误 - 错误:关系“msysnavpanegroups”不存在错误:关系“msysnavpanegrouptoobjects”不存在我也收到错误时试图加载数据(它的循环和说列不存在)。你知道为什么会这样吗?
首先我会先将mdb-schema
的输出定向到文件,以验证输出。每当您从一个系统迁移到另一个系统时,都会出现不匹配的情况。 Access 数据库中有msysnavpanegroups
表吗?是否在mdb-schema
生成的输出中?哪一列不存在,确切的错误是什么?将上面的答案添加到您的问题中。
【参考方案1】:
我最终使用了pyodbc
和pywin32
的组合。 pywin32
是“基本上是一个非常薄的 python 包装器,它允许我们与 COM 对象交互并使用 python 自动化 Windows 应用程序”(引自下面的第二个链接)。
我能够以编程方式与 Access 交互,并使用 DoCmd.TransferDatabase
将表直接导出到 Postgres
https://docs.microsoft.com/en-us/office/vba/api/access.docmd.transferdatabase https://pbpython.com/windows-com.html
import win32com.client
import pyodbc
import logging
from pathlib import Path
conn_str = (r'DRIVER=Microsoft Access Driver (*.mdb, *.accdb); 'rf'DBQ=access_database_location;')
conn = pyodbc.connect(conn_str)
cursor = conn.cursor()
a = win32com.client.Dispatch("Access.Application")
a.OpenCurrentDatabase(access_database_location)
table_list = []
for table_info in cursor.tables(tableType='TABLE'):
table_list.append(table_info.table_name)
for table in table_list:
logging.info(f"Exporting: table")
acExport = 1
acTable = 0
db_name = Path(access_database_location).stem.lower()
a.DoCmd.TransferDatabase(acExport, "ODBC Database", "ODBC;DRIVER=PostgreSQL Unicode;"f"DATABASE=db_name;"f"UID=pg_user;"f"PWD=pg_pwd;""SERVER=localhost;"f"PORT=pg_port;", acTable, f"table", f"table.lower()_export_from_access")
logging.info(f"Finished Export of Table: table")
logging.info("Creating empty table in EGDB based off of this")
这种方法似乎对我有用。我喜欢如何自动处理表/字段的创建以及数据的插入(这是我在pyodbc
遇到的原始问题)。
如果有人有更好的方法,我愿意接受建议。
【讨论】:
以上是关于如何使用 pyodbc 将表从 MS Access 迁移到 Postgres?的主要内容,如果未能解决你的问题,请参考以下文章