Mod: database is now stable.
Improved convenience and documention.
This commit is contained in:
parent
00f7279c6d
commit
a4e9a8f8dc
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@ -8,5 +8,5 @@
|
|||||||
"python.linting.enabled": true,
|
"python.linting.enabled": true,
|
||||||
"python.linting.pylintEnabled": false,
|
"python.linting.pylintEnabled": false,
|
||||||
"python.linting.flake8Enabled": true,
|
"python.linting.flake8Enabled": true,
|
||||||
"python.linting.flake8Args": ["--ignore=E402,E251,E501,E201,E202,W293,W291,W504", "--verbose"]
|
"python.linting.flake8Args": ["--ignore=E402,E251,E501,E201,E202,W293,W291,W504,E203", "--verbose"]
|
||||||
}
|
}
|
@ -1,11 +1,13 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from .models import __models__
|
from . import utils
|
||||||
from .db import Database
|
from . import tables
|
||||||
|
|
||||||
class tables:
|
from .database import Database
|
||||||
pass
|
|
||||||
|
|
||||||
for model in __models__:
|
|
||||||
setattr(tables, model.__name__, model)
|
__all__ = [
|
||||||
|
"utils",
|
||||||
|
"tables",
|
||||||
|
"Database"
|
||||||
|
]
|
||||||
|
238
anisotropy/database/database.py
Normal file
238
anisotropy/database/database.py
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
from numpy import ndarray
|
||||||
|
|
||||||
|
import peewee as pw
|
||||||
|
import pathlib
|
||||||
|
import time
|
||||||
|
|
||||||
|
from . import tables
|
||||||
|
|
||||||
|
|
||||||
|
class Database(pw.SqliteDatabase):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
"""A Database object contains SQLite database with convient
|
||||||
|
properties and methods
|
||||||
|
"""
|
||||||
|
self.filepath = kwargs.get("path", None)
|
||||||
|
self.pragmas_ = kwargs.get("pragmas", { "foreign_keys": 1, "journal_mode": "wal" })
|
||||||
|
self.field_types_ = kwargs.get("field_types", { "list": "text" })
|
||||||
|
self.autoconnect_ = kwargs.get("autoconnect", False)
|
||||||
|
|
||||||
|
pw.SqliteDatabase.__init__(
|
||||||
|
self,
|
||||||
|
None,
|
||||||
|
pragmas = self.pragmas_,
|
||||||
|
field_types = self.field_types_,
|
||||||
|
autoconnect = self.autoconnect_
|
||||||
|
)
|
||||||
|
|
||||||
|
if self.filepath:
|
||||||
|
self.setup()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def tables(self) -> list:
|
||||||
|
"""Return all tables as list.
|
||||||
|
"""
|
||||||
|
return [ tables.__dict__[table] for table in tables.__all__ ]
|
||||||
|
|
||||||
|
def setup(self, filename: str = None):
|
||||||
|
"""Initialize database and create tables.
|
||||||
|
|
||||||
|
:param filename:
|
||||||
|
Path to the file.
|
||||||
|
:return:
|
||||||
|
Self.
|
||||||
|
"""
|
||||||
|
self.filepath = pathlib.Path(filename or self.filepath).resolve()
|
||||||
|
self.init(
|
||||||
|
self.filepath,
|
||||||
|
pragmas = self.pragmas_
|
||||||
|
)
|
||||||
|
tables.database_proxy.initialize(self)
|
||||||
|
|
||||||
|
with self:
|
||||||
|
self.create_tables(self.tables)
|
||||||
|
|
||||||
|
return self
|
||||||
|
|
||||||
|
def csave(self, table: pw.Model, tries: int = 100):
|
||||||
|
"""Try to save data from model to the database ignoring
|
||||||
|
peewee.OperationalError. Usefull for concurrent processes.
|
||||||
|
|
||||||
|
:param table:
|
||||||
|
Table to save.
|
||||||
|
:param tries:
|
||||||
|
Number of tries. Falling to sleep for 1 second if database
|
||||||
|
is locked.
|
||||||
|
"""
|
||||||
|
while tries >= 0:
|
||||||
|
if self.is_closed():
|
||||||
|
self.connect()
|
||||||
|
|
||||||
|
try:
|
||||||
|
table.save()
|
||||||
|
|
||||||
|
except pw.OperationalError:
|
||||||
|
tries -= 1
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
else:
|
||||||
|
self.close()
|
||||||
|
break
|
||||||
|
|
||||||
|
def getExecution(self, idn: int) -> tables.Execution | None:
|
||||||
|
"""Get execution entry from database.
|
||||||
|
|
||||||
|
:param idn:
|
||||||
|
Index of the execution.
|
||||||
|
:return:
|
||||||
|
If entry is found returns Model instance else None.
|
||||||
|
"""
|
||||||
|
query = tables.Execution.select().where(tables.Execution.exec_id == idn)
|
||||||
|
|
||||||
|
with self:
|
||||||
|
table = query.get() if query.exists() else None
|
||||||
|
|
||||||
|
return table
|
||||||
|
|
||||||
|
def getLatest(self) -> tables.Execution | None:
|
||||||
|
"""Get latest execution entry from database.
|
||||||
|
|
||||||
|
:return:
|
||||||
|
If entry is found returns Model instance else None.
|
||||||
|
"""
|
||||||
|
query = tables.Execution.select()
|
||||||
|
|
||||||
|
with self:
|
||||||
|
table = query[-1] if query.exists() else None
|
||||||
|
|
||||||
|
return table
|
||||||
|
|
||||||
|
def getShape(
|
||||||
|
self,
|
||||||
|
label: str = None,
|
||||||
|
direction: list[float] | ndarray = None,
|
||||||
|
alpha: float = None,
|
||||||
|
execution: int = None,
|
||||||
|
**kwargs
|
||||||
|
) -> tables.Shape | None:
|
||||||
|
"""Get shape entry from database.
|
||||||
|
|
||||||
|
:param label:
|
||||||
|
Label of the shape.
|
||||||
|
:param direction:
|
||||||
|
Array of floats represents direction vector.
|
||||||
|
:param alpha:
|
||||||
|
Spheres overlap parameter.
|
||||||
|
:param execution:
|
||||||
|
Index of the execution. If None, use latest.
|
||||||
|
:return:
|
||||||
|
If entry is found returns Model instance else None.
|
||||||
|
"""
|
||||||
|
execution = execution or self.getLatest()
|
||||||
|
query = (
|
||||||
|
tables.Shape
|
||||||
|
.select()
|
||||||
|
.join(tables.Execution, pw.JOIN.LEFT_OUTER)
|
||||||
|
.where(
|
||||||
|
tables.Execution.exec_id == execution,
|
||||||
|
tables.Shape.label == label,
|
||||||
|
tables.Shape.direction == direction,
|
||||||
|
tables.Shape.alpha == alpha
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
with self:
|
||||||
|
table = query.get() if query.exists() else None
|
||||||
|
|
||||||
|
return table
|
||||||
|
|
||||||
|
def getMesh(
|
||||||
|
self,
|
||||||
|
label: str = None,
|
||||||
|
direction: list[float] | ndarray = None,
|
||||||
|
alpha: float = None,
|
||||||
|
execution: int = None,
|
||||||
|
**kwargs
|
||||||
|
) -> tables.Mesh | None:
|
||||||
|
"""Get mesh entry from database.
|
||||||
|
|
||||||
|
:param label:
|
||||||
|
Label of the shape.
|
||||||
|
:param direction:
|
||||||
|
Array of floats represents direction vector.
|
||||||
|
:param alpha:
|
||||||
|
Spheres overlap parameter.
|
||||||
|
:param execution:
|
||||||
|
Index of the execution. If None, use latest.
|
||||||
|
:return:
|
||||||
|
If entry is found returns Model instance else None.
|
||||||
|
"""
|
||||||
|
execution = execution or self.getLatest()
|
||||||
|
query = (
|
||||||
|
tables.Mesh
|
||||||
|
.select()
|
||||||
|
.join(tables.Shape, pw.JOIN.LEFT_OUTER)
|
||||||
|
.join(tables.Execution, pw.JOIN.LEFT_OUTER)
|
||||||
|
.where(
|
||||||
|
tables.Execution.exec_id == execution,
|
||||||
|
tables.Shape.label == label,
|
||||||
|
tables.Shape.direction == direction,
|
||||||
|
tables.Shape.alpha == alpha
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
with self:
|
||||||
|
table = query.get() if query.exists() else None
|
||||||
|
|
||||||
|
return table
|
||||||
|
|
||||||
|
def getFlowOnephase(
|
||||||
|
self,
|
||||||
|
label: str = None,
|
||||||
|
direction: list[float] | ndarray = None,
|
||||||
|
alpha: float = None,
|
||||||
|
execution: int = None,
|
||||||
|
to_dict: bool = False,
|
||||||
|
**kwargs
|
||||||
|
) -> tables.Mesh | dict | None:
|
||||||
|
"""Get one phase flow entry from database.
|
||||||
|
|
||||||
|
:param label:
|
||||||
|
Label of the shape.
|
||||||
|
:param direction:
|
||||||
|
Array of floats represents direction vector.
|
||||||
|
:param alpha:
|
||||||
|
Spheres overlap parameter.
|
||||||
|
:param execution:
|
||||||
|
Index of the execution. If None, use latest.
|
||||||
|
:param to_dict:
|
||||||
|
If True, convert result to dict.
|
||||||
|
:return:
|
||||||
|
If entry is found returns Model instance or dict else None.
|
||||||
|
"""
|
||||||
|
execution = execution or self.getLatest()
|
||||||
|
query = (
|
||||||
|
tables.FlowOnephase
|
||||||
|
.select()
|
||||||
|
.join(tables.Mesh, pw.JOIN.LEFT_OUTER)
|
||||||
|
.join(tables.Shape, pw.JOIN.LEFT_OUTER)
|
||||||
|
.join(tables.Execution, pw.JOIN.LEFT_OUTER)
|
||||||
|
.where(
|
||||||
|
tables.Execution.exec_id == execution,
|
||||||
|
tables.Shape.label == label,
|
||||||
|
tables.Shape.direction == direction,
|
||||||
|
tables.Shape.alpha == alpha
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
with self:
|
||||||
|
if to_dict:
|
||||||
|
table = query.dicts().get() if query.exists() else None
|
||||||
|
|
||||||
|
else:
|
||||||
|
table = query.get() if query.exists() else None
|
||||||
|
|
||||||
|
return table
|
@ -1,140 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# This file is part of anisotropy.
|
|
||||||
# License: GNU GPL version 3, see the file "LICENSE" for details.
|
|
||||||
|
|
||||||
import os
|
|
||||||
from peewee import SqliteDatabase, JOIN, OperationalError
|
|
||||||
from . import models
|
|
||||||
|
|
||||||
class Database(SqliteDatabase):
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
self.filepath = kwargs.get("path", None)
|
|
||||||
self.pragmas_ = kwargs.get("pragmas", { "foreign_keys": 1, "journal_mode": "wal" })
|
|
||||||
self.field_types_ = kwargs.get("field_types", { "list": "text" })
|
|
||||||
self.autoconnect_ = kwargs.get("autoconnect", False)
|
|
||||||
|
|
||||||
SqliteDatabase.__init__(
|
|
||||||
self,
|
|
||||||
None,
|
|
||||||
pragmas = self.pragmas_,
|
|
||||||
field_types = self.field_types_,
|
|
||||||
autoconnect = self.autoconnect_
|
|
||||||
)
|
|
||||||
|
|
||||||
if self.filepath:
|
|
||||||
self.setup()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def tables(self):
|
|
||||||
return models.__models__
|
|
||||||
|
|
||||||
def setup(self, filename: str = None):
|
|
||||||
#if not self.filepath:
|
|
||||||
self.filepath = os.path.abspath(filename or self.filepath)
|
|
||||||
self.init(
|
|
||||||
self.filepath,
|
|
||||||
pragmas = self.pragmas_,
|
|
||||||
#field_types = self.field_types_,
|
|
||||||
#autoconnect = self.autoconnect_
|
|
||||||
)
|
|
||||||
models.__database_proxy__.initialize(self)
|
|
||||||
|
|
||||||
with self:
|
|
||||||
self.create_tables(self.tables)
|
|
||||||
|
|
||||||
def csave(self, table, tries: int = 100):
|
|
||||||
while tries >= 0:
|
|
||||||
if self.is_closed():
|
|
||||||
self.connect()
|
|
||||||
|
|
||||||
try:
|
|
||||||
table.save()
|
|
||||||
|
|
||||||
except OperationalError as e:
|
|
||||||
logger.debug(e)
|
|
||||||
tries -= 1
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
else:
|
|
||||||
self.close()
|
|
||||||
break
|
|
||||||
|
|
||||||
def getExecution(self, idn):
|
|
||||||
query = models.Execution.select().where(models.Execution.exec_id == idn)
|
|
||||||
|
|
||||||
with self:
|
|
||||||
table = query.get() if query.exists() else None
|
|
||||||
|
|
||||||
return table
|
|
||||||
|
|
||||||
def getLatest(self):
|
|
||||||
query = models.Execution.select()
|
|
||||||
|
|
||||||
with self:
|
|
||||||
table = query[-1] if query.exists() else None
|
|
||||||
|
|
||||||
return table
|
|
||||||
|
|
||||||
def getShape(self, label = None, direction = None, alpha = None, execution = None, **kwargs):
|
|
||||||
execution = execution or self.getLatest()
|
|
||||||
query = (
|
|
||||||
models.Shape
|
|
||||||
.select()
|
|
||||||
.join(models.Execution, JOIN.LEFT_OUTER)
|
|
||||||
.where(
|
|
||||||
models.Execution.exec_id == execution,
|
|
||||||
models.Shape.label == label,
|
|
||||||
models.Shape.direction == direction,
|
|
||||||
models.Shape.alpha == alpha
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
with self:
|
|
||||||
table = query.get() if query.exists() else None
|
|
||||||
|
|
||||||
return table
|
|
||||||
|
|
||||||
def getMesh(self, label = None, direction = None, alpha = None, execution = None, **kwargs):
|
|
||||||
execution = execution or self.getLatest()
|
|
||||||
query = (
|
|
||||||
models.Mesh
|
|
||||||
.select()
|
|
||||||
.join(models.Shape, JOIN.LEFT_OUTER)
|
|
||||||
.join(models.Execution, JOIN.LEFT_OUTER)
|
|
||||||
.where(
|
|
||||||
models.Execution.exec_id == execution,
|
|
||||||
models.Shape.label == label,
|
|
||||||
models.Shape.direction == direction,
|
|
||||||
models.Shape.alpha == alpha
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
with self:
|
|
||||||
table = query.get() if query.exists() else None
|
|
||||||
|
|
||||||
return table
|
|
||||||
|
|
||||||
def getFlowOnephase(self, label = None, direction = None, alpha = None, execution = None, to_dict = False, **kwargs):
|
|
||||||
execution = execution or self.getLatest()
|
|
||||||
query = (
|
|
||||||
models.FlowOnephase
|
|
||||||
.select()
|
|
||||||
.join(models.Mesh, JOIN.LEFT_OUTER)
|
|
||||||
.join(models.Shape, JOIN.LEFT_OUTER)
|
|
||||||
.join(models.Execution, JOIN.LEFT_OUTER)
|
|
||||||
.where(
|
|
||||||
models.Execution.exec_id == execution,
|
|
||||||
models.Shape.label == label,
|
|
||||||
models.Shape.direction == direction,
|
|
||||||
models.Shape.alpha == alpha
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
with self:
|
|
||||||
if to_dict:
|
|
||||||
table = query.dicts().get() if query.exists() else None
|
|
||||||
|
|
||||||
else:
|
|
||||||
table = query.get() if query.exists() else None
|
|
||||||
|
|
||||||
return table
|
|
@ -1,108 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# This file is part of anisotropy.
|
|
||||||
# License: GNU GPL version 3, see the file "LICENSE" for details.
|
|
||||||
|
|
||||||
from peewee import (
|
|
||||||
SqliteDatabase, JOIN,
|
|
||||||
Model, Field,
|
|
||||||
AutoField, ForeignKeyField,
|
|
||||||
TextField, FloatField,
|
|
||||||
IntegerField, BooleanField,
|
|
||||||
TimeField, DateTimeField, Proxy
|
|
||||||
)
|
|
||||||
from .utils import JSONField
|
|
||||||
|
|
||||||
__database_proxy__ = Proxy()
|
|
||||||
|
|
||||||
class Execution(Model):
|
|
||||||
exec_id = AutoField()
|
|
||||||
|
|
||||||
date = DateTimeField()
|
|
||||||
executionTime = TimeField(null = True)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
database = __database_proxy__
|
|
||||||
table_name = "executions"
|
|
||||||
|
|
||||||
|
|
||||||
class Shape(Model):
|
|
||||||
shape_id = AutoField()
|
|
||||||
exec_id = ForeignKeyField(Execution, backref = "executions", on_delete = "CASCADE")
|
|
||||||
|
|
||||||
shapeStatus = TextField(null = True, default = "idle")
|
|
||||||
shapeExecutionTime = TimeField(null = True)
|
|
||||||
|
|
||||||
label = TextField(null = True)
|
|
||||||
direction = JSONField(null = True)
|
|
||||||
alpha = FloatField(null = True)
|
|
||||||
|
|
||||||
r0 = FloatField(null = True)
|
|
||||||
L = FloatField(null = True)
|
|
||||||
radius = FloatField(null = True)
|
|
||||||
|
|
||||||
filletsEnabled = BooleanField(null = True)
|
|
||||||
fillets = FloatField(null = True)
|
|
||||||
|
|
||||||
volumeCell = FloatField(null = True)
|
|
||||||
volume = FloatField(null = True)
|
|
||||||
porosity = FloatField(null = True)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
database = __database_proxy__
|
|
||||||
table_name = "shapes"
|
|
||||||
#depends_on = Execution
|
|
||||||
|
|
||||||
|
|
||||||
class Mesh(Model):
|
|
||||||
mesh_id = AutoField()
|
|
||||||
shape_id = ForeignKeyField(Shape, backref = "shapes", on_delete = "CASCADE")
|
|
||||||
|
|
||||||
meshStatus = TextField(null = True, default = "idle")
|
|
||||||
meshExecutionTime = TimeField(null = True)
|
|
||||||
|
|
||||||
elements = IntegerField(null = True)
|
|
||||||
edges = IntegerField(null = True)
|
|
||||||
faces = IntegerField(null = True)
|
|
||||||
volumes = IntegerField(null = True)
|
|
||||||
tetrahedrons = IntegerField(null = True)
|
|
||||||
prisms = IntegerField(null = True)
|
|
||||||
pyramids = IntegerField(null = True)
|
|
||||||
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
database = __database_proxy__
|
|
||||||
table_name = "meshes"
|
|
||||||
#depends_on = Execution
|
|
||||||
|
|
||||||
|
|
||||||
class FlowOnephase(Model):
|
|
||||||
flow_id = AutoField()
|
|
||||||
mesh_id = ForeignKeyField(Mesh, backref = "meshes", on_delete = "CASCADE")
|
|
||||||
|
|
||||||
flowStatus = TextField(null = True, default = "idle")
|
|
||||||
flowExecutionTime = TimeField(null = True)
|
|
||||||
|
|
||||||
pressureInlet = FloatField(null = True)
|
|
||||||
pressureOutlet = FloatField(null = True)
|
|
||||||
pressureInternal = FloatField(null = True)
|
|
||||||
velocityInlet = JSONField(null = True)
|
|
||||||
velocityOutlet = JSONField(null = True)
|
|
||||||
velocityInternal = JSONField(null = True)
|
|
||||||
viscosity = FloatField(null = True)
|
|
||||||
viscosityKinematic = FloatField(null = True)
|
|
||||||
density = FloatField(null = True)
|
|
||||||
flowRate = FloatField(null = True)
|
|
||||||
permeability = FloatField(null = True)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
database = __database_proxy__
|
|
||||||
table_name = "flows"
|
|
||||||
#depends_on = Execution
|
|
||||||
|
|
||||||
|
|
||||||
__models__ = [
|
|
||||||
Execution,
|
|
||||||
Shape,
|
|
||||||
Mesh,
|
|
||||||
FlowOnephase
|
|
||||||
]
|
|
102
anisotropy/database/tables.py
Normal file
102
anisotropy/database/tables.py
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import peewee as pw
|
||||||
|
|
||||||
|
from . import utils
|
||||||
|
|
||||||
|
|
||||||
|
# proxy, assign database later
|
||||||
|
database_proxy = pw.Proxy()
|
||||||
|
|
||||||
|
|
||||||
|
class Execution(pw.Model):
|
||||||
|
exec_id = pw.AutoField()
|
||||||
|
|
||||||
|
date = pw.DateTimeField()
|
||||||
|
executionTime = pw.TimeField(null = True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
database = database_proxy
|
||||||
|
table_name = "executions"
|
||||||
|
|
||||||
|
|
||||||
|
class Shape(pw.Model):
|
||||||
|
shape_id = pw.AutoField()
|
||||||
|
exec_id = pw.ForeignKeyField(Execution, backref = "executions", on_delete = "CASCADE")
|
||||||
|
|
||||||
|
shapeStatus = pw.TextField(null = True, default = "idle")
|
||||||
|
shapeExecutionTime = pw.TimeField(null = True)
|
||||||
|
|
||||||
|
label = pw.TextField(null = True)
|
||||||
|
direction = utils.JSONField(null = True)
|
||||||
|
alpha = pw.FloatField(null = True)
|
||||||
|
|
||||||
|
r0 = pw.FloatField(null = True)
|
||||||
|
L = pw.FloatField(null = True)
|
||||||
|
radius = pw.FloatField(null = True)
|
||||||
|
|
||||||
|
filletsEnabled = pw.BooleanField(null = True)
|
||||||
|
fillets = pw.FloatField(null = True)
|
||||||
|
|
||||||
|
volumeCell = pw.FloatField(null = True)
|
||||||
|
volume = pw.FloatField(null = True)
|
||||||
|
porosity = pw.FloatField(null = True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
database = database_proxy
|
||||||
|
table_name = "shapes"
|
||||||
|
# depends_on = Execution
|
||||||
|
|
||||||
|
|
||||||
|
class Mesh(pw.Model):
|
||||||
|
mesh_id = pw.AutoField()
|
||||||
|
shape_id = pw.ForeignKeyField(Shape, backref = "shapes", on_delete = "CASCADE")
|
||||||
|
|
||||||
|
meshStatus = pw.TextField(null = True, default = "idle")
|
||||||
|
meshExecutionTime = pw.TimeField(null = True)
|
||||||
|
|
||||||
|
elements = pw.IntegerField(null = True)
|
||||||
|
edges = pw.IntegerField(null = True)
|
||||||
|
faces = pw.IntegerField(null = True)
|
||||||
|
volumes = pw.IntegerField(null = True)
|
||||||
|
tetrahedrons = pw.IntegerField(null = True)
|
||||||
|
prisms = pw.IntegerField(null = True)
|
||||||
|
pyramids = pw.IntegerField(null = True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
database = database_proxy
|
||||||
|
table_name = "meshes"
|
||||||
|
# depends_on = Execution
|
||||||
|
|
||||||
|
|
||||||
|
class FlowOnephase(pw.Model):
|
||||||
|
flow_id = pw.AutoField()
|
||||||
|
mesh_id = pw.ForeignKeyField(Mesh, backref = "meshes", on_delete = "CASCADE")
|
||||||
|
|
||||||
|
flowStatus = pw.TextField(null = True, default = "idle")
|
||||||
|
flowExecutionTime = pw.TimeField(null = True)
|
||||||
|
|
||||||
|
pressureInlet = pw.FloatField(null = True)
|
||||||
|
pressureOutlet = pw.FloatField(null = True)
|
||||||
|
pressureInternal = pw.FloatField(null = True)
|
||||||
|
velocityInlet = utils.JSONField(null = True)
|
||||||
|
velocityOutlet = utils.JSONField(null = True)
|
||||||
|
velocityInternal = utils.JSONField(null = True)
|
||||||
|
viscosity = pw.FloatField(null = True)
|
||||||
|
viscosityKinematic = pw.FloatField(null = True)
|
||||||
|
density = pw.FloatField(null = True)
|
||||||
|
flowRate = pw.FloatField(null = True)
|
||||||
|
permeability = pw.FloatField(null = True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
database = database_proxy
|
||||||
|
table_name = "flows"
|
||||||
|
# depends_on = Execution
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"Execution",
|
||||||
|
"Shape",
|
||||||
|
"Mesh",
|
||||||
|
"FlowOnephase"
|
||||||
|
]
|
@ -1,22 +1,12 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# This file is part of anisotropy.
|
|
||||||
# License: GNU GPL version 3, see the file "LICENSE" for details.
|
|
||||||
|
|
||||||
from peewee import (
|
|
||||||
TextField,
|
|
||||||
ColumnBase,
|
|
||||||
Value,
|
|
||||||
fn,
|
|
||||||
Node,
|
|
||||||
Expression,
|
|
||||||
OP,
|
|
||||||
Field
|
|
||||||
)
|
|
||||||
import json
|
|
||||||
from numpy import ndarray
|
from numpy import ndarray
|
||||||
|
|
||||||
|
import peewee as pw
|
||||||
|
import json
|
||||||
|
|
||||||
class ListField(TextField):
|
|
||||||
|
class ListField(pw.TextField):
|
||||||
field_type = "list"
|
field_type = "list"
|
||||||
|
|
||||||
def db_value(self, value):
|
def db_value(self, value):
|
||||||
@ -29,88 +19,78 @@ class ListField(TextField):
|
|||||||
try:
|
try:
|
||||||
pval.append(float(entry))
|
pval.append(float(entry))
|
||||||
|
|
||||||
except:
|
except Exception:
|
||||||
pval.append(entry.strip().replace("'", ""))
|
pval.append(entry.strip().replace("'", ""))
|
||||||
|
|
||||||
return pval
|
return pval
|
||||||
|
|
||||||
"""
|
|
||||||
class JSONField(TextField):
|
|
||||||
# TODO: fix double quotes when use __eq__ in 'where' method
|
|
||||||
field_type = "TEXT"
|
|
||||||
|
|
||||||
def db_value(self, value):
|
class JSONPath(pw.ColumnBase):
|
||||||
if isinstance(value, ndarray):
|
def __init__(self, field, path = None):
|
||||||
formatted = list(value)
|
|
||||||
|
|
||||||
else:
|
|
||||||
formatted = value
|
|
||||||
|
|
||||||
return json.dumps(formatted)
|
|
||||||
|
|
||||||
def python_value(self, value):
|
|
||||||
if value is not None:
|
|
||||||
return json.loads(value)
|
|
||||||
"""
|
|
||||||
|
|
||||||
class JSONPath(ColumnBase):
|
|
||||||
def __init__(self, field, path=None):
|
|
||||||
super(JSONPath, self).__init__()
|
super(JSONPath, self).__init__()
|
||||||
|
|
||||||
self._field = field
|
self._field = field
|
||||||
self._path = path or ()
|
self._path = path or ()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def path(self):
|
def path(self):
|
||||||
return Value('$%s' % ''.join(self._path))
|
return pw.Value('$%s' % ''.join(self._path))
|
||||||
|
|
||||||
def __getitem__(self, idx):
|
def __getitem__(self, idx):
|
||||||
if isinstance(idx, int):
|
if isinstance(idx, int):
|
||||||
item = '[%s]' % idx
|
item = '[%s]' % idx
|
||||||
|
|
||||||
else:
|
else:
|
||||||
item = '.%s' % idx
|
item = '.%s' % idx
|
||||||
|
|
||||||
return JSONPath(self._field, self._path + (item,))
|
return JSONPath(self._field, self._path + (item,))
|
||||||
|
|
||||||
def set(self, value, as_json=None):
|
def set(self, value, as_json = None):
|
||||||
if as_json or isinstance(value, (list, dict)):
|
if as_json or isinstance(value, (list, dict)):
|
||||||
value = fn.json(self._field._json_dumps(value))
|
value = pw.fn.json(self._field._json_dumps(value))
|
||||||
return fn.json_set(self._field, self.path, value)
|
|
||||||
|
return pw.fn.json_set(self._field, self.path, value)
|
||||||
|
|
||||||
def update(self, value):
|
def update(self, value):
|
||||||
return self.set(fn.json_patch(self, self._field._json_dumps(value)))
|
return self.set(pw.fn.json_patch(self, self._field._json_dumps(value)))
|
||||||
|
|
||||||
def remove(self):
|
def remove(self):
|
||||||
return fn.json_remove(self._field, self.path)
|
return pw.fn.json_remove(self._field, self.path)
|
||||||
|
|
||||||
def json_type(self):
|
def json_type(self):
|
||||||
return fn.json_type(self._field, self.path)
|
return pw.fn.json_type(self._field, self.path)
|
||||||
|
|
||||||
def length(self):
|
def length(self):
|
||||||
return fn.json_array_length(self._field, self.path)
|
return pw.fn.json_array_length(self._field, self.path)
|
||||||
|
|
||||||
def children(self):
|
def children(self):
|
||||||
return fn.json_each(self._field, self.path)
|
return pw.fn.json_each(self._field, self.path)
|
||||||
|
|
||||||
def tree(self):
|
def tree(self):
|
||||||
return fn.json_tree(self._field, self.path)
|
return pw.fn.json_tree(self._field, self.path)
|
||||||
|
|
||||||
def __sql__(self, ctx):
|
def __sql__(self, ctx):
|
||||||
return ctx.sql(fn.json_extract(self._field, self.path)
|
return ctx.sql(
|
||||||
if self._path else self._field)
|
pw.fn.json_extract(self._field, self.path)
|
||||||
|
if self._path else self._field
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class JSONField(TextField):
|
class JSONField(pw.TextField):
|
||||||
field_type = 'TEXT'
|
field_type = 'TEXT'
|
||||||
unpack = False
|
unpack = False
|
||||||
|
|
||||||
def __init__(self, json_dumps=None, json_loads=None, **kwargs):
|
def __init__(self, json_dumps = None, json_loads = None, **kwargs):
|
||||||
|
super(JSONField, self).__init__(**kwargs)
|
||||||
|
|
||||||
self._json_dumps = json_dumps or json.dumps
|
self._json_dumps = json_dumps or json.dumps
|
||||||
self._json_loads = json_loads or json.loads
|
self._json_loads = json_loads or json.loads
|
||||||
super(JSONField, self).__init__(**kwargs)
|
|
||||||
|
|
||||||
def python_value(self, value):
|
def python_value(self, value):
|
||||||
if value is not None:
|
if value is not None:
|
||||||
try:
|
try:
|
||||||
return json.loads(value)
|
return json.loads(value)
|
||||||
|
|
||||||
except (TypeError, ValueError):
|
except (TypeError, ValueError):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
@ -119,28 +99,32 @@ class JSONField(TextField):
|
|||||||
if isinstance(value, ndarray):
|
if isinstance(value, ndarray):
|
||||||
value = list(value)
|
value = list(value)
|
||||||
|
|
||||||
if not isinstance(value, Node):
|
if not isinstance(value, pw.Node):
|
||||||
value = json.dumps(value)
|
value = json.dumps(value)
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def _e(op):
|
def _e(op):
|
||||||
def inner(self, rhs):
|
def inner(self, rhs):
|
||||||
if isinstance(rhs, (list, dict)):
|
if isinstance(rhs, (list, dict)):
|
||||||
rhs = Value(rhs, converter=self.db_value, unpack=False)
|
rhs = pw.Value(rhs, converter = self.db_value, unpack = False)
|
||||||
return Expression(self, op, rhs)
|
|
||||||
|
return pw.Expression(self, op, rhs)
|
||||||
|
|
||||||
return inner
|
return inner
|
||||||
__eq__ = _e(OP.EQ)
|
|
||||||
__ne__ = _e(OP.NE)
|
__eq__ = _e(pw.OP.EQ)
|
||||||
__gt__ = _e(OP.GT)
|
__ne__ = _e(pw.OP.NE)
|
||||||
__ge__ = _e(OP.GTE)
|
__gt__ = _e(pw.OP.GT)
|
||||||
__lt__ = _e(OP.LT)
|
__ge__ = _e(pw.OP.GTE)
|
||||||
__le__ = _e(OP.LTE)
|
__lt__ = _e(pw.OP.LT)
|
||||||
__hash__ = Field.__hash__
|
__le__ = _e(pw.OP.LTE)
|
||||||
|
__hash__ = pw.Field.__hash__
|
||||||
|
|
||||||
def __getitem__(self, item):
|
def __getitem__(self, item):
|
||||||
return JSONPath(self)[item]
|
return JSONPath(self)[item]
|
||||||
|
|
||||||
def set(self, value, as_json=None):
|
def set(self, value, as_json = None):
|
||||||
return JSONPath(self).set(value, as_json)
|
return JSONPath(self).set(value, as_json)
|
||||||
|
|
||||||
def update(self, data):
|
def update(self, data):
|
||||||
@ -150,10 +134,10 @@ class JSONField(TextField):
|
|||||||
return JSONPath(self).remove()
|
return JSONPath(self).remove()
|
||||||
|
|
||||||
def json_type(self):
|
def json_type(self):
|
||||||
return fn.json_type(self)
|
return pw.fn.json_type(self)
|
||||||
|
|
||||||
def length(self):
|
def length(self):
|
||||||
return fn.json_array_length(self)
|
return pw.fn.json_array_length(self)
|
||||||
|
|
||||||
def children(self):
|
def children(self):
|
||||||
"""
|
"""
|
||||||
@ -170,8 +154,7 @@ class JSONField(TextField):
|
|||||||
json JSON hidden (1st input parameter to function)
|
json JSON hidden (1st input parameter to function)
|
||||||
root TEXT hidden (2nd input parameter, path at which to start)
|
root TEXT hidden (2nd input parameter, path at which to start)
|
||||||
"""
|
"""
|
||||||
return fn.json_each(self)
|
return pw.fn.json_each(self)
|
||||||
|
|
||||||
def tree(self):
|
def tree(self):
|
||||||
return fn.json_tree(self)
|
return pw.fn.json_tree(self)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user