Model, BC: Add SQL export for boundary condition.

results
Pierre-Antoine Rouby 2023-06-29 15:39:35 +02:00
parent 4978f20e29
commit 36f792d432
5 changed files with 202 additions and 16 deletions

View File

@ -2,15 +2,24 @@
from tools import trace, timer, old_pamhyr_date_to_timestamp from tools import trace, timer, old_pamhyr_date_to_timestamp
from Model.DB import SQLSubModel
from Model.Except import NotImplementedMethodeError from Model.Except import NotImplementedMethodeError
class BoundaryCondition(object): class BoundaryCondition(SQLSubModel):
def __init__(self, name:str = "", _sub_classes = []
_id_cnt = 0
def __init__(self, id:int = -1, name:str = "",
status = None): status = None):
super(BoundaryCondition, self).__init__() super(BoundaryCondition, self).__init__()
self._status = status self._status = status
if id == -1:
self.id = type(self)._id_cnt
else:
self.id = id
self._name = name self._name = name
self._type = "" self._type = ""
self._node = None self._node = None
@ -18,6 +27,131 @@ class BoundaryCondition(object):
self._header = [] self._header = []
self._types = [float, float] self._types = [float, float]
type(self)._id_cnt = max(type(self)._id_cnt + 1, self.id)
@classmethod
def _sql_create(cls, execute):
execute("""
CREATE TABLE boundary_condition(
id INTEGER NOT NULL PRIMARY KEY,
name TEXT NOT NULL,
type TEXT NOT NULL,
tab TEXT NOT NULL,
node INTEGER,
FOREIGN KEY(node) REFERENCES river_node(id)
)
""")
execute("""
CREATE TABLE boundary_condition_data(
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
ind INTEGER NOT NULL,
data0 TEXT NOT NULL,
data1 TEXT NOT NULL,
bc INTEGER,
FOREIGN KEY(bc) REFERENCES boundary_condition(id)
)
""")
return cls._create_submodel(execute)
@classmethod
def _sql_update(cls, execute, version):
return True
@classmethod
def _get_ctor_from_type(cls, t):
from Model.BoundaryCondition.BoundaryConditionTypes import (
NotDefined, PonctualContribution,
TimeOverZ, TimeOverDischarge, ZOverDischarge
)
res = NotDefined
if t == "PC":
res = PonctualContribution
elif t == "TZ":
res = TimeOverZ
elif t == "TD":
res = TimeOverDischarge
elif t == "ZD":
res = ZOverDischarge
return res
@classmethod
def _sql_load(cls, execute, data = None):
new = []
tab = data["tab"]
table = execute(
"SELECT id, name, type, node " +
"FROM boundary_condition " +
f"WHERE tab = '{tab}'"
)
for row in table:
t = row[2]
ctor = cls._get_ctor_from_type(t)
bc = ctor(
id = row[0],
name = row[1],
status = data['status']
)
bc.node = next(filter(lambda n: n.id == row[3], data["nodes"]))
values = execute(
"SELECT ind, data0, data1 FROM boundary_condition_data " +
f"WHERE bc = '{bc.id}'"
)
# Create dummy data list
for _ in values:
bc.add(0)
# Write data
for v in values:
ind = v[0]
data0 = bc._types[0](v[1])
data1 = bc._types[1](v[2])
# Replace data at pos ind
bc._data[ind] = (data0, data1)
new.append(bc)
return new
def _sql_save(self, execute, data = None):
tab = data["tab"]
execute(f"DELETE FROM boundary_condition WHERE id = {self.id}")
execute(f"DELETE FROM boundary_condition_data WHERE bc = {self.id}")
node = -1
if self._node is not None:
node = self._node.id
sql = (
"INSERT INTO " +
"boundary_condition(id, name, type, tab, node) "+
"VALUES (" +
f"{self.id}, '{self._sql_format(self._name)}', " +
f"'{self._sql_format(self._type)}', '{tab}', {node}" +
")"
)
execute(sql)
ind = 0
for d in self._data:
data0 = self._sql_format(str(d[0]))
data1 = self._sql_format(str(d[1]))
sql = (
"INSERT INTO " +
"boundary_condition_data(ind, data0, data1, bc) "+
f"VALUES ({ind}, '{data0}', {data1}, {self.id})"
)
execute(sql)
ind += 1
return True
def __len__(self): def __len__(self):
return len(self._data) return len(self._data)

View File

@ -3,15 +3,21 @@
from copy import copy from copy import copy
from tools import trace, timer from tools import trace, timer
from Model.DB import SQLSubModel
from Model.Except import NotImplementedMethodeError from Model.Except import NotImplementedMethodeError
from Model.BoundaryCondition.BoundaryCondition import BoundaryCondition
from Model.BoundaryCondition.BoundaryConditionTypes import ( from Model.BoundaryCondition.BoundaryConditionTypes import (
NotDefined, NotDefined,
PonctualContribution, PonctualContribution,
TimeOverZ, TimeOverDischarge, ZOverDischarge TimeOverZ, TimeOverDischarge, ZOverDischarge
) )
class BoundaryConditionList(object): class BoundaryConditionList(SQLSubModel):
_sub_classes = [
BoundaryCondition,
]
def __init__(self, status = None): def __init__(self, status = None):
super(BoundaryConditionList, self).__init__() super(BoundaryConditionList, self).__init__()
@ -23,6 +29,40 @@ class BoundaryConditionList(object):
"suspenssion" : [] "suspenssion" : []
} }
@classmethod
def _sql_create(cls, execute):
return cls._create_submodel(execute)
@classmethod
def _sql_update(cls, execute, version):
return True
@classmethod
def _sql_load(cls, execute, data = None):
new = cls(status = data['status'])
if data is None:
data = {}
for tab in new._tabs:
data["tab"] = tab
new._tabs[tab] = BoundaryCondition._sql_load(
execute, data
)
return new
def _sql_save(self, execute, data = None):
if data is None:
data = {}
for tab in self._tabs:
data["tab"] = tab
for bc in self._tabs[tab]:
bc._sql_save(execute, data = data)
return True
def len(self, lst): def len(self, lst):
return len(self._tabs[lst]) return len(self._tabs[lst])

View File

@ -6,8 +6,8 @@ from Model.BoundaryCondition.BoundaryCondition import BoundaryCondition
class NotDefined(BoundaryCondition): class NotDefined(BoundaryCondition):
def __init__(self, name:str = "", status = None): def __init__(self, id:int = -1, name:str = "", status = None):
super(NotDefined, self).__init__(name=name, status=status) super(NotDefined, self).__init__(id=id, name=name, status=status)
self._type = "ND" self._type = "ND"
self._header = ["x", "y"] self._header = ["x", "y"]
@ -17,8 +17,8 @@ class NotDefined(BoundaryCondition):
return 0.0 return 0.0
class PonctualContribution(BoundaryCondition): class PonctualContribution(BoundaryCondition):
def __init__(self, name:str = "", status = None): def __init__(self, id:int = -1, name:str = "", status = None):
super(PonctualContribution, self).__init__(name=name, status=status) super(PonctualContribution, self).__init__(id=id, name=name, status=status)
self._type = "PC" self._type = "PC"
self._header = ["time", "discharge"] self._header = ["time", "discharge"]
@ -29,8 +29,8 @@ class PonctualContribution(BoundaryCondition):
return ["liquid"] return ["liquid"]
class TimeOverZ(BoundaryCondition): class TimeOverZ(BoundaryCondition):
def __init__(self, name:str = "", status = None): def __init__(self, id:int = -1, name:str = "", status = None):
super(TimeOverZ, self).__init__(name=name, status=status) super(TimeOverZ, self).__init__(id=id, name=name, status=status)
self._type = "TZ" self._type = "TZ"
self._header = ["time", "z"] self._header = ["time", "z"]
@ -41,8 +41,8 @@ class TimeOverZ(BoundaryCondition):
return ["liquid"] return ["liquid"]
class TimeOverDischarge(BoundaryCondition): class TimeOverDischarge(BoundaryCondition):
def __init__(self, name:str = "", status = None): def __init__(self, id:int = -1, name:str = "", status = None):
super(TimeOverDischarge, self).__init__(name=name, status=status) super(TimeOverDischarge, self).__init__(id=id, name=name, status=status)
self._type = "TD" self._type = "TD"
self._header = ["time", "discharge"] self._header = ["time", "discharge"]
@ -53,8 +53,8 @@ class TimeOverDischarge(BoundaryCondition):
return ["liquid"] return ["liquid"]
class ZOverDischarge(BoundaryCondition): class ZOverDischarge(BoundaryCondition):
def __init__(self, name:str = "", status = None): def __init__(self, id:int = -1, name:str = "", status = None):
super(ZOverDischarge, self).__init__(name=name, status=status) super(ZOverDischarge, self).__init__(id=id, name=name, status=status)
self._type = "ZD" self._type = "ZD"
self._header = ["z", "discharge"] self._header = ["z", "discharge"]

View File

@ -48,7 +48,7 @@ class RiverNode(Node, SQLSubModel):
@classmethod @classmethod
def _sql_update(cls, execute, version): def _sql_update(cls, execute, version):
return None return True
@classmethod @classmethod
def _sql_load(cls, execute, data = None): def _sql_load(cls, execute, data = None):
@ -171,7 +171,7 @@ class River(Graph, SQLSubModel):
_sub_classes = [ _sub_classes = [
RiverNode, RiverNode,
RiverReach, RiverReach,
# BoundaryConditionList, BoundaryConditionList,
# LateralContributionList, # LateralContributionList,
# InitialConditionsDict, # InitialConditionsDict,
# StricklersList, # StricklersList,
@ -204,21 +204,32 @@ class River(Graph, SQLSubModel):
@classmethod @classmethod
def _sql_load(cls, execute, data = None): def _sql_load(cls, execute, data = None):
# Network
new = cls(data["status"]) new = cls(data["status"])
new._nodes = RiverNode._sql_load( new._nodes = RiverNode._sql_load(
execute, execute,
data data
) )
data["nodes"] = new.nodes() data["nodes"] = new.nodes()
new._edges = RiverReach._sql_load( new._edges = RiverReach._sql_load(
execute, execute,
data data
) )
data["edges"] = new.edges()
# Boundary Condition
new._boundary_condition = BoundaryConditionList._sql_load(
execute,
data
)
return new return new
def _sql_save(self, execute, data = None): def _sql_save(self, execute, data = None):
objs = self._nodes + self._edges objs = (self._nodes + self._edges)
objs.append(self._boundary_condition)
self._save_submodel(execute, objs, data) self._save_submodel(execute, objs, data)
return True return True

View File

@ -232,6 +232,7 @@ class SQL(object):
return value return value
def execute(self, cmd, fetch_one = True, commit = False): def execute(self, cmd, fetch_one = True, commit = False):
print(f"[SQL] {cmd}")
res = self._cur.execute(cmd) res = self._cur.execute(cmd)
if commit: if commit: