如何使用 pyodbc 将表从 MS Access 迁移到 Postgres?

How to use pyodbc to migrate tables from MS Access to Postgres?

我需要将 tables 从 MS Access 迁移到 Postgres。我想使用 pyodbc 来执行此操作,因为它允许我使用 python 连接到 Access 数据库并查询数据。

我遇到的问题是,除了使用字符串格式创建 SQL 语句之外,我不确定如何以编程方式创建具有相同架构的 table。 pyodbc 提供了列出所有字段、字段类型和字段长度的功能,因此我可以创建一个包含所有相关信息的长 SQL 语句,但是我如何才能为一堆 tables?我需要为每个 table 构建 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 语句。我知道我可以手动构建一个长字符串,但如果我正在做一堆不同的 tables,具有不同的字段等,那将是不现实的。是否有更好、更简单的方法来创建 table 并根据 Access 数据库的架构插入行?

我最终使用了 pyodbcpywin32 的组合。 pywin32“基本上是 python 的一个非常薄的包装器,它允许我们与 COM 对象交互并使用 python 自动化 Windows 应用程序”(引自第二个 link下面)。

我能够以编程方式与 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")

这种方法似乎对我有用。我喜欢如何自动处理 table/fields 的创建以及数据的插入(这是我在使用 pyodbc 时遇到的原始问题)。

如果有人有更好的方法,我愿意接受建议。