补全图层
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -79,19 +79,43 @@ class MapService:
|
|||||||
return model["name"]
|
return model["name"]
|
||||||
|
|
||||||
def _fix_invalid_layers(self, project: QgsProject) -> None:
|
def _fix_invalid_layers(self, project: QgsProject) -> None:
|
||||||
"""只修复 TemplateModifier 处理后仍无效的图层"""
|
"""修复 TemplateModifier 处理后仍无效的 PostgreSQL 图层。
|
||||||
|
|
||||||
|
批量查询 DB 确认表存在性,只对存在的表执行 setDataSource 修复。
|
||||||
|
"""
|
||||||
t0 = time.time()
|
t0 = time.time()
|
||||||
db_config = self.config["db"]
|
db_config = self.config["db"]
|
||||||
actual_schema = "qgis"
|
actual_schema = "qgis"
|
||||||
|
|
||||||
fixed = 0
|
invalid_pg = []
|
||||||
failed = 0
|
valid_count = 0
|
||||||
total = 0
|
total = 0
|
||||||
for layer in project.mapLayers().values():
|
for layer in project.mapLayers().values():
|
||||||
if layer.providerType() != "postgres":
|
if layer.providerType() != "postgres":
|
||||||
continue
|
continue
|
||||||
total += 1
|
total += 1
|
||||||
if layer.isValid():
|
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
|
continue
|
||||||
try:
|
try:
|
||||||
self._fix_postgres_layer(layer, db_config, actual_schema)
|
self._fix_postgres_layer(layer, db_config, actual_schema)
|
||||||
@@ -106,10 +130,53 @@ class MapService:
|
|||||||
elapsed = time.time() - t0
|
elapsed = time.time() - t0
|
||||||
if total:
|
if total:
|
||||||
logger.info(
|
logger.info(
|
||||||
f" 图层修正: 总计{total}个PG层, 跳过{total - fixed - failed}(已有效), "
|
f" 图层修正: 总计{total}个PG层, 有效{valid_count}, "
|
||||||
f"修复{fixed}, 仍失败{failed}, 耗时{elapsed:.1f}s"
|
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
|
@staticmethod
|
||||||
def _fix_postgres_layer(layer, db_config, actual_schema):
|
def _fix_postgres_layer(layer, db_config, actual_schema):
|
||||||
"""修正单个 PostgreSQL 图层的连接参数"""
|
"""修正单个 PostgreSQL 图层的连接参数"""
|
||||||
|
|||||||
Reference in New Issue
Block a user