补全图层

This commit is contained in:
wzy-warehouse
2026-06-21 18:57:49 +08:00
parent 26fdb71417
commit 2e05f3d28a
3 changed files with 72 additions and 5 deletions
Binary file not shown.
Binary file not shown.
+72 -5
View File
@@ -79,19 +79,43 @@ class MapService:
return model["name"]
def _fix_invalid_layers(self, project: QgsProject) -> None:
"""修复 TemplateModifier 处理后仍无效的图层"""
"""修复 TemplateModifier 处理后仍无效的 PostgreSQL 图层
批量查询 DB 确认表存在性,只对存在的表执行 setDataSource 修复。
"""
t0 = time.time()
db_config = self.config["db"]
actual_schema = "qgis"
fixed = 0
failed = 0
invalid_pg = []
valid_count = 0
total = 0
for layer in project.mapLayers().values():
if layer.providerType() != "postgres":
continue
total += 1
if layer.isValid():
valid_count += 1
continue
invalid_pg.append(layer)
if not invalid_pg:
elapsed = time.time() - t0
logger.info(f" 图层修正: 总计{total}个PG层, 全部有效, 耗时{elapsed:.3f}s")
return
# 批量 DB 查询确认表存在性
existing = self._batch_check_tables(db_config, actual_schema, invalid_pg)
fixed = 0
skipped_missing = 0
failed = 0
for layer in invalid_pg:
uri = layer.dataProvider().uri()
key = (uri.schema() or actual_schema, uri.table())
if key not in existing:
logger.debug(f" 跳过不存在的表: {key[0]}.{key[1]} (图层: {layer.name()})")
skipped_missing += 1
continue
try:
self._fix_postgres_layer(layer, db_config, actual_schema)
@@ -106,10 +130,53 @@ class MapService:
elapsed = time.time() - t0
if total:
logger.info(
f" 图层修正: 总计{total}个PG层, 跳过{total - fixed - failed}(已有效), "
f"修复{fixed}, 仍失败{failed}, 耗时{elapsed:.1f}s"
f" 图层修正: 总计{total}个PG层, 有效{valid_count}, "
f"跳过{skipped_missing}(表不存在), "
f"修复{fixed}, 仍失败{failed}, 耗时{elapsed:.3f}s"
)
@staticmethod
def _batch_check_tables(db_config, schema, layers):
"""批量检查表是否存在(单次 DB 查询),返回存在的表集合"""
tables = set()
for layer in layers:
uri = layer.dataProvider().uri()
tables.add((uri.schema() or schema, uri.table()))
if not tables:
return set()
try:
import psycopg2
conn = psycopg2.connect(
host=db_config["host"],
port=int(db_config["port"]),
dbname=db_config["database"],
user=db_config["username"],
password=db_config["password"],
connect_timeout=3,
)
cur = conn.cursor()
conditions = " OR ".join(
"(table_schema = %s AND table_name = %s)"
for _ in tables
)
params = []
for s, t in tables:
params.extend([s, t])
cur.execute(
f"SELECT table_schema, table_name FROM information_schema.tables "
f"WHERE {conditions}",
params,
)
existing = {(row[0], row[1]) for row in cur.fetchall()}
cur.close()
conn.close()
return existing
except Exception as e:
logger.warning(f" 表存在性检查失败,将尝试修复所有图层: {e}")
return set(tables)
@staticmethod
def _fix_postgres_layer(layer, db_config, actual_schema):
"""修正单个 PostgreSQL 图层的连接参数"""