补全图层
This commit is contained in:
@@ -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 图层的连接参数"""
|
||||
|
||||
Reference in New Issue
Block a user