-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Enable migrations from older database schemas. (#1764)
Fixes Deltares/Ribasim-NL#138 This has no schema version (stored in the geopackage) yet, but this is something we could implement in the future. --------- Co-authored-by: Marnix <[email protected]>
- Loading branch information
1 parent
23bbbbc
commit 8d89e74
Showing
16 changed files
with
302 additions
and
87 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
from contextlib import closing | ||
from pathlib import Path | ||
from sqlite3 import Connection, connect | ||
|
||
|
||
def esc_id(identifier: str) -> str: | ||
"""Escape SQLite identifiers.""" | ||
identifier = identifier.replace('"', '""') | ||
return f'"{identifier}"' | ||
|
||
|
||
def exists(connection: Connection, name: str) -> bool: | ||
"""Check if a table exists in a SQLite database.""" | ||
with closing(connection.cursor()) as cursor: | ||
cursor.execute( | ||
"SELECT name FROM sqlite_master WHERE type='table' AND name=?", (name,) | ||
) | ||
result = cursor.fetchone() | ||
return result is not None | ||
|
||
|
||
def _set_gpkg_attribute_table(connection: Connection, table: str) -> None: | ||
# Set geopackage attribute table | ||
with closing(connection.cursor()) as cursor: | ||
sql = "INSERT OR REPLACE INTO gpkg_contents (table_name, data_type, identifier) VALUES (?, ?, ?)" | ||
cursor.execute(sql, (table, "attributes", table)) | ||
connection.commit() | ||
|
||
|
||
CREATE_TABLE_SQL = """ | ||
CREATE TABLE IF NOT EXISTS ribasim_metadata ( | ||
key TEXT PRIMARY KEY, | ||
value TEXT | ||
); | ||
""" | ||
|
||
|
||
def _get_db_schema_version(db_path: Path) -> int: | ||
""" | ||
Get the schema version of the database. | ||
For older models, the version is assumed to be zero, | ||
which is smaller than the initial schema version of the database. | ||
""" | ||
with closing(connect(db_path)) as connection: | ||
if not exists(connection, "ribasim_metadata"): | ||
return 0 | ||
with closing(connection.cursor()) as cursor: | ||
cursor.execute( | ||
"SELECT value FROM ribasim_metadata WHERE key='schema_version'" | ||
) | ||
return int(cursor.fetchone()[0]) | ||
|
||
|
||
def _set_db_schema_version(db_path: Path, version: int = 1) -> None: | ||
with closing(connect(db_path)) as connection: | ||
if not exists(connection, "metadata"): | ||
with closing(connection.cursor()) as cursor: | ||
cursor.execute(CREATE_TABLE_SQL) | ||
cursor.execute( | ||
"INSERT OR REPLACE INTO ribasim_metadata (key, value) VALUES ('schema_version', ?)", | ||
(version,), | ||
) | ||
_set_gpkg_attribute_table(connection, "ribasim_metadata") | ||
connection.commit() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import warnings | ||
|
||
from geopandas import GeoDataFrame | ||
from pandas import DataFrame | ||
|
||
|
||
def nodeschema_migration(gdf: GeoDataFrame) -> GeoDataFrame: | ||
if "node_id" in gdf.columns: | ||
warnings.warn("Migrating outdated Node table.", UserWarning) | ||
assert gdf["node_id"].is_unique, "Node IDs have to be unique." | ||
gdf.set_index("node_id", inplace=True) | ||
|
||
return gdf | ||
|
||
|
||
def edgeschema_migration(gdf: GeoDataFrame) -> GeoDataFrame: | ||
if "from_node_type" in gdf.columns: | ||
warnings.warn("Migrating outdated Edge table.", UserWarning) | ||
gdf.drop("from_node_type", inplace=True, axis=1) | ||
if "to_node_type" in gdf.columns: | ||
warnings.warn("Migrating outdated Edge table.", UserWarning) | ||
gdf.drop("to_node_type", inplace=True, axis=1) | ||
if "edge_id" in gdf.columns: | ||
warnings.warn("Migrating outdated Edge table.", UserWarning) | ||
gdf.set_index("edge_id", inplace=True) | ||
|
||
return gdf | ||
|
||
|
||
def basinstaticschema_migration(df: DataFrame) -> DataFrame: | ||
if "urban_runoff" in df.columns: | ||
warnings.warn("Migrating outdated Basin / Static table.", UserWarning) | ||
df.drop("urban_runoff", inplace=True, axis=1) | ||
|
||
return df | ||
|
||
|
||
def basintimeschema_migration(df: DataFrame) -> DataFrame: | ||
if "urban_runoff" in df.columns: | ||
warnings.warn("Migrating outdated Basin / Time table.", UserWarning) | ||
df.drop("urban_runoff", inplace=True, axis=1) | ||
|
||
return df | ||
|
||
|
||
def continuouscontrolvariableschema_migration(df: DataFrame) -> DataFrame: | ||
if "listen_node_type" in df.columns: | ||
warnings.warn( | ||
"Migrating outdated ContinuousControl / Variable table.", UserWarning | ||
) | ||
df.drop("listen_node_type", inplace=True, axis=1) | ||
|
||
return df | ||
|
||
|
||
def discretecontrolvariableschema_migration(df: DataFrame) -> DataFrame: | ||
if "listen_node_type" in df.columns: | ||
warnings.warn( | ||
"Migrating outdated DiscreteControl / Variable table.", UserWarning | ||
) | ||
df.drop("listen_node_type", inplace=True, axis=1) | ||
|
||
return df | ||
|
||
|
||
def pidcontrolstaticschema_migration(df: DataFrame) -> DataFrame: | ||
if "listen_node_type" in df.columns: | ||
warnings.warn("Migrating outdated PidControl / Static table.", UserWarning) | ||
df.drop("listen_node_type", inplace=True, axis=1) | ||
|
||
return df |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.