# -*- coding: utf-8 -*- """ 在 zqyy_app 和 test_zqyy_app 中执行 FDW 配置。 - zqyy_app -> setup_fdw.sql (指向 etl_feiqiu) - test_zqyy_app -> setup_fdw_test.sql (指向 test_etl_feiqiu) """ import os import psycopg2 CONN = dict(host="100.64.0.4", port=5432, user="local-Python", password="Neo-local-1991125") BASE = r"C:\NeoZQYY" # 实际密码替换占位符 '***' APP_READER_PWD = "AppR3ad_2026!" TARGETS = [ ("zqyy_app", os.path.join(BASE, "db", "fdw", "setup_fdw.sql")), ("test_zqyy_app", os.path.join(BASE, "db", "fdw", "setup_fdw_test.sql")), ] for dbname, sql_path in TARGETS: print(f"\n{'='*60}") print(f"执行 FDW 配置: {dbname} <- {os.path.basename(sql_path)}") print(f"{'='*60}") sql = open(sql_path, encoding="utf-8").read() # 替换密码占位符 sql = sql.replace("password '***'", f"password '{APP_READER_PWD}'") conn = psycopg2.connect(**CONN, dbname=dbname) conn.autocommit = True cur = conn.cursor() # 逐条执行(按分号拆分,跳过注释和空行) statements = [] current = [] for line in sql.split("\n"): stripped = line.strip() if stripped.startswith("--") or not stripped: continue current.append(line) if stripped.endswith(";"): statements.append("\n".join(current)) current = [] success = 0 skip = 0 fail = 0 for stmt in statements: try: cur.execute(stmt) first_line = stmt.strip().split("\n")[0][:80] print(f" [OK] {first_line}") success += 1 except psycopg2.errors.DuplicateObject as e: conn.rollback() print(f" [SKIP] 已存在: {str(e).strip().split(chr(10))[0]}") skip += 1 except Exception as e: conn.rollback() print(f" [FAIL] {str(e).strip().split(chr(10))[0]}") print(f" SQL: {stmt[:100]}") fail += 1 # 验证 cur.execute("SELECT 1 FROM pg_extension WHERE extname = 'postgres_fdw'") fdw_ext = cur.fetchone() is not None cur.execute("SELECT srvname FROM pg_foreign_server") servers = [r[0] for r in cur.fetchall()] cur.execute( "SELECT count(*) FROM information_schema.tables " "WHERE table_schema = 'fdw_etl'" ) fdw_tables = cur.fetchone()[0] print(f"\n 结果: {success} OK, {skip} SKIP, {fail} FAIL") print(f" 验证: fdw扩展={fdw_ext}, servers={servers}, fdw_etl表数={fdw_tables}") conn.close() print("\n完成!")