refactor(db)!: finalize pooled WNDB v2 migration

This commit is contained in:
2026-08-27 17:26:22 +08:00
parent fa188af0b1
commit b74799a39d
105 changed files with 4988 additions and 5565 deletions
+69 -67
View File
@@ -1,18 +1,26 @@
import datetime
import logging
import os
from tempfile import NamedTemporaryFile
from psycopg import sql
from ..core.projects import (
close_project,
create_project,
copy_project,
delete_project,
have_project,
is_project_open,
open_project,
temporary_project_name,
temporary_template_database,
)
from app.infra.db.project_routing import get_project_template_database_name
from ..core.connection import project_transaction
from ..core.database import ChangeSet, refresh_materialized_views, sql_literal, write
from ..core.model_replace import replace_project_model
from ..core.database import (
ChangeSet,
refresh_materialized_views_after_commit,
sql_literal,
write,
)
from .sections import (
BACKDROP,
BOUND,
@@ -68,7 +76,7 @@ from ..model.reactions import inp_in_reaction
from ..model.mixing import inp_in_mixing
from ..model.times import inp_in_time
from ..model.reports import inp_in_report
from ..model.options_legacy import inp_in_option
from ..model.options_v2 import inp_in_option_v2
from ..model.options_v3 import inp_in_option_v3
from ..gis.coordinates import inp_in_coord
from ..gis.vertices import inp_in_vertex
@@ -82,10 +90,11 @@ from .exporter import export_inp
_S = "S"
_L = "L"
logger = logging.getLogger(__name__)
def _inp_in_option(section: list[str], version: str = "3") -> str:
return inp_in_option_v3(section) if version == "3" else inp_in_option(section)
return inp_in_option_v3(section) if version == "3" else inp_in_option_v2(section)
_handler = {
@@ -389,60 +398,49 @@ def read_inp(project: str, inp: str, version: str = "3") -> bool:
if version != "3" and version != "2":
version = "2"
if is_project_open(project):
close_project(project)
if not have_project(project):
raise ValueError(f"Project database {project!r} does not exist")
if have_project(project):
delete_project(project)
staging_project = temporary_project_name(project, "model_import")
replacement_committed = False
try:
copy_project(get_project_template_database_name(project), staging_project)
with project_transaction(staging_project):
parse_file(staging_project, inp, version)
replace_project_model(project, staging_project)
replacement_committed = True
finally:
try:
if have_project(staging_project):
delete_project(staging_project)
except Exception:
logger.exception(
"Failed to remove model-import staging database %s",
staging_project,
)
create_project(project)
open_project(project)
if replacement_committed:
refresh_materialized_views_after_commit(project)
with project_transaction(project):
parse_file(project, inp, version)
refresh_materialized_views(project)
"""try:
parse_file(project, inp, version)
except:
close_project(project)
delete_project(project)
return False"""
close_project(project)
return True
# DingZQ, 2024-12-28, convert v3 to v2
def convert_inp_v3_to_v2(inp: str) -> ChangeSet:
project = "v3Tov2"
if is_project_open(project):
close_project(project)
if have_project(project):
delete_project(project)
create_project(project)
open_project(project)
filename = f"inp/{project}_temp.inp"
if os.path.exists(filename):
os.remove(filename)
with open(filename, "w", encoding="utf-8") as f:
f.write(inp)
parse_file(project, filename, "3")
"""try:
parse_file(project, inp, version)
except:
close_project(project)
delete_project(project)
return False"""
return export_inp(project, "2")
temp_path: str | None = None
with temporary_template_database("conversion", "v3_to_v2") as project:
try:
with NamedTemporaryFile(
mode="w", suffix=".inp", encoding="utf-8", delete=False
) as temp_file:
temp_file.write(inp)
temp_path = temp_file.name
with project_transaction(project):
parse_file(project, temp_path, "3")
return export_inp(project, "2")
finally:
if temp_path is not None:
os.remove(temp_path)
def import_inp(project: str, cs: ChangeSet, version: str = "3") -> bool:
@@ -452,17 +450,21 @@ def import_inp(project: str, cs: ChangeSet, version: str = "3") -> bool:
if "inp" not in cs.operations[0]:
return False
filename = f"inp/{project}_temp.inp"
if os.path.exists(filename):
os.remove(filename)
_print_time(f'Start writing temp file "{filename}"...')
with open(filename, "w", encoding="utf-8") as f:
f.write(str(cs.operations[0]["inp"]))
_print_time(f'End writing temp file "{filename}"...')
result = read_inp(project, filename, version)
# os.remove(filename)
return result
temp_path: str | None = None
try:
with NamedTemporaryFile(
mode="w",
suffix=".inp",
prefix="tjwater_import_",
encoding="utf-8",
delete=False,
) as temp_file:
temp_file.write(str(cs.operations[0]["inp"]))
temp_path = temp_file.name
return read_inp(project, temp_path, version)
finally:
if temp_path is not None:
try:
os.remove(temp_path)
except FileNotFoundError:
pass