- Consolidated database, file source, and field mapping configurations into dedicated modules under the `config` directory. - Removed hardcoded database connection details from `migration.py` and replaced them with imports from the new configuration structure. - Updated `ntfy_utils.py` and `run_incremental_sync.py` to utilize the new configuration imports for cleaner code and better maintainability. - Deleted `update_config.py` as its contents have been integrated into the new configuration files. - Added a new `settings.local.json` for managing permissions related to script execution. - Enhanced the structure of the migration tasks and Excel configurations for better organization and clarity.
35 lines
1.3 KiB
Python
35 lines
1.3 KiB
Python
# db_utils.py
|
|
import pyodbc
|
|
from config import SQL_SERVER_CONN, ACCESS_DRIVER
|
|
|
|
def get_sql_conn():
|
|
"""获取 SQL Server 连接"""
|
|
# 显式添加 TrustServerCertificate=yes 以兼容 ODBC Driver 18+
|
|
conn_str = (
|
|
f"DRIVER={SQL_SERVER_CONN['driver']};SERVER={SQL_SERVER_CONN['server']};"
|
|
f"DATABASE={SQL_SERVER_CONN['database']};UID={SQL_SERVER_CONN['uid']};PWD={SQL_SERVER_CONN['pwd']};"
|
|
"Encrypt=yes;TrustServerCertificate=yes;"
|
|
)
|
|
return pyodbc.connect(conn_str)
|
|
|
|
def get_access_conn(file_path):
|
|
"""获取 Access 连接"""
|
|
conn_str = f"DRIVER={ACCESS_DRIVER};DBQ={file_path};"
|
|
return pyodbc.connect(conn_str)
|
|
|
|
def fmt_table(schema, table):
|
|
"""格式化 SQL Server 表名 [schema].[table]"""
|
|
return f"[{schema}].[{table}]"
|
|
|
|
def get_columns(cursor, table_name):
|
|
"""获取 Access 表的列名"""
|
|
# Access 查询表名加 []
|
|
cursor.execute(f"SELECT TOP 1 * FROM [{table_name}]")
|
|
return [column[0] for column in cursor.description]
|
|
|
|
def generate_insert_sql(target_schema, target_table, columns):
|
|
"""生成带架构的 INSERT 语句"""
|
|
full_table_name = fmt_table(target_schema, target_table)
|
|
col_str = ",".join([f"[{col}]" for col in columns])
|
|
placeholders = ",".join(["?"] * len(columns))
|
|
return f"INSERT INTO {full_table_name} ({col_str}) VALUES ({placeholders})" |