Skip to content

Commit

Permalink
Editing date and timestamp values
Browse files Browse the repository at this point in the history
  • Loading branch information
wuwwen authored and ryan-kipawa committed Nov 28, 2024
1 parent a595c07 commit 02f6f2f
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 95 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,8 @@
- Fix inserting fails silently when no value is provided for 'Seq'
- Handle Nullable value more user friendly
- Added insert data with geometry and update geometry function

## [2024.1.0] - 2024-11-28

### Added
- Editing date and timestamp values
13 changes: 13 additions & 0 deletions mikeplus/datatableaccess.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
from DHI.Amelia.DataModule.Services.DataTables import AmlUndoRedoManager

from .dotnet import as_dotnet_list
from .dotnet import from_dotnet_datetime
from .dotnet import to_dotnet_datetime
from datetime import datetime


class DataTableAccess:
Expand Down Expand Up @@ -143,6 +146,8 @@ def get_field_values(self, table_name, muid, fields):
if values[i] is not None:
wkt = GeoAPIHelper.GetWKTIGeometry(values[i])
pyValues.append(wkt)
elif isinstance(values[i], System.DateTime):
pyValues.append(from_dotnet_datetime(values[i]))
else:
pyValues.append(values[i])
i += 1
Expand Down Expand Up @@ -182,6 +187,8 @@ def get_muid_field_values(self, table_name, fields, where=None):
if val is not None:
wkt = GeoAPIHelper.GetWKTIGeometry(val)
mylist.append(wkt)
elif isinstance(val, System.DateTime):
mylist.append(from_dotnet_datetime(val))
else:
mylist.append(val)
mydict[feildVal.Key] = mylist
Expand Down Expand Up @@ -222,6 +229,8 @@ def set_value(self, table_name, muid, column, value):
geomTable = IMuGeomTable(self._datatables[table_name])
geomTable.UpdateGeomByCommand(muid, geom)
else:
if isinstance(value, datetime):
value = to_dotnet_datetime(value)
self._datatables[table_name].SetValueByCommand(muid, column, value)

def set_values(self, table_name, muid, values):
Expand Down Expand Up @@ -259,6 +268,8 @@ def set_values(self, table_name, muid, values):
geom = GeoAPIHelper.GetIGeometryFromWKT(wkt)
geomTable = IMuGeomTable(self._datatables[table_name])
geomTable.UpdateGeomByCommand(muid, geom)
elif isinstance(values[col], datetime):
value_dict[col] = to_dotnet_datetime(values[col])
else:
value_dict[col] = values[col]
self._datatables[table_name].SetValuesByCommand(muid, value_dict)
Expand Down Expand Up @@ -300,6 +311,8 @@ def insert(self, table_name, muid, values=None):
geom = GeoAPIHelper.GetIGeometryFromWKT(wkt)
if isinstance(values[col], int):
value_dict[col] = System.Nullable[int](values[col])
elif isinstance(values[col], datetime):
value_dict[col] = to_dotnet_datetime(values[col])
else:
value_dict[col] = values[col]
result, new_muid = self._datatables[table_name].InsertByCommand(
Expand Down
32 changes: 32 additions & 0 deletions mikeplus/dotnet.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import clr # noqa: F401

import System
from System import String
from System.Collections.Generic import List
import datetime


def as_dotnet_list(py_list: list, dotnet_type=None):
Expand Down Expand Up @@ -32,3 +34,33 @@ def as_dotnet_list(py_list: list, dotnet_type=None):
for item in py_list:
dotnet_list.Add(item)
return dotnet_list


def to_dotnet_datetime(x):
"""Convert from python datetime to .NET System.DateTime."""
dotnet_datetime = System.DateTime(
x.year, x.month, x.day, x.hour, x.minute, x.second
)
# Get .NET ticks microseconds
ticks = x.microsecond * 10
dotnet_datetime = dotnet_datetime.AddTicks(ticks)
return dotnet_datetime


def from_dotnet_datetime(x, round_to_milliseconds=True):
"""Convert from .NET System.DateTime to python datetime."""
# Get microseconds from .NET ticks
microseconds = x.Ticks % 10**7 // 10
time = datetime.datetime(
x.Year, x.Month, x.Day, x.Hour, x.Minute, x.Second, microseconds
)

# Round to milliseconds if requested
if round_to_milliseconds:
microseconds_rounded = round(time.microsecond, -3)
if microseconds_rounded == 10**6:
time += datetime.timedelta(seconds=1)
microseconds_rounded = 0
time = time.replace(microsecond=microseconds_rounded)

return time
161 changes: 66 additions & 95 deletions notebooks/DataTableAccessor.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -85,28 +85,17 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": null,
"id": "a0dfb0ce",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"outputs": [],
"source": [
"data_access.is_database_open()"
]
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": null,
"id": "cfabd6c4",
"metadata": {},
"outputs": [],
Expand All @@ -121,39 +110,21 @@
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": null,
"id": "28644d8f",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['link_test']\n"
]
}
],
"outputs": [],
"source": [
"query = data_access.get_muid_where(\"msm_Link\", \"MUID='link_test'\")\n",
"print(query)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": null,
"id": "6dff5333",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Diameter:2.0\n",
"Description:insertValues\n",
"geometry:LINESTRING (3 4, 10 50, 20 25)\n"
]
}
],
"outputs": [],
"source": [
"fields = [\"Diameter\", \"Description\", \"geometry\"]\n",
"values = data_access.get_field_values(\"msm_Link\", \"link_test\", fields)\n",
Expand All @@ -162,20 +133,10 @@
},
{
"cell_type": "code",
"execution_count": 7,
"execution_count": null,
"id": "b12d1430",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Diameter:1.0\n",
"Description:setValues\n",
"geometry:LINESTRING (4 5, 20 60, 30 35)\n"
]
}
],
"outputs": [],
"source": [
"values = {\n",
" \"Diameter\": 1.0,\n",
Expand All @@ -189,18 +150,10 @@
},
{
"cell_type": "code",
"execution_count": 8,
"execution_count": null,
"id": "fa039e4e",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"geometry:LINESTRING (5 6, 30 70, 40 45)\n"
]
}
],
"outputs": [],
"source": [
"\"\"\"Update link geometry\"\"\"\n",
"data_access.set_value(\n",
Expand All @@ -213,7 +166,7 @@
},
{
"cell_type": "code",
"execution_count": 9,
"execution_count": null,
"id": "10797bb4",
"metadata": {},
"outputs": [],
Expand All @@ -223,29 +176,10 @@
},
{
"cell_type": "code",
"execution_count": 10,
"execution_count": null,
"id": "f45ece86",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"node has been inserted, current data is:\n",
"GeomX:6.0\n",
"GeomY:10.0\n",
"geometry:POINT (6 10)\n",
"GeomX has been updated, current data is:\n",
"GeomX:8.0\n",
"GeomY:10.0\n",
"geometry:POINT (8 10)\n",
"geometry has been updated, current data is:\n",
"GeomX:8.0\n",
"GeomY:10.0\n",
"geometry:POINT (8 10)\n"
]
}
],
"outputs": [],
"source": [
"\"\"\"Insert node with geometry of wkt format, and update node coordinate x and y\"\"\"\n",
"values = {\"geometry\": \"POINT(6 10)\"}\n",
Expand All @@ -266,21 +200,10 @@
},
{
"cell_type": "code",
"execution_count": 11,
"execution_count": null,
"id": "d9fcd4f5",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"link has been inserted, current data is:\n",
"geometry:LINESTRING (0 0, 10 10)\n",
"link geometry has been updated, current data is:\n",
"geometry:LINESTRING (10 10, 20 20)\n"
]
}
],
"outputs": [],
"source": [
"\"\"\"Insert line with geometry of shapely object, and update geometry with shapely object\"\"\"\n",
"from shapely.geometry import LineString\n",
Expand All @@ -297,12 +220,60 @@
"values = data_access.get_field_values(\"msm_Link\", \"link_shp_test\", fields)\n",
"print(\"link geometry has been updated, current data is:\")\n",
"print_field_values(fields, values)\n",
"data_access.delete(\"msm_Link\", \"link_shp_test\")\n"
"data_access.delete(\"msm_Link\", \"link_shp_test\")"
]
},
{
"cell_type": "code",
"execution_count": 12,
"execution_count": null,
"id": "aeb30396",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"ComputationBegin:01-11-2023 01:00:00\n",
"ComputationEnd:01-11-2023 02:00:00\n"
]
}
],
"source": [
"\"\"\"Change start time and end time for simulation\"\"\"\n",
"from datetime import datetime\n",
"\n",
"values = {\n",
" \"ComputationBegin\": datetime(2023, 11, 1, 0, 0, 0, 0),\n",
" \"ComputationEnd\": datetime(2023, 11, 1, 1, 0, 0, 0),\n",
"}\n",
"data_access.insert(\"msm_Project\", \"sim_test\", values)\n",
"fields = [\"ComputationBegin\", \"ComputationEnd\"]\n",
"values = data_access.get_field_values(\"msm_Project\", \"sim_test\", fields)\n",
"print_field_values(fields, values)\n",
"\n",
"values = {\n",
" \"ComputationBegin\": datetime(2023, 11, 1, 1, 0, 0, 0),\n",
" \"ComputationEnd\": datetime(2023, 11, 1, 2, 0, 0, 0),\n",
"}\n",
"data_access.set_values(\"msm_Project\", \"sim_test\", values)\n",
"values = data_access.get_field_values(\"msm_Project\", \"sim_test\", fields)\n",
"print_field_values(fields, values)\n",
"data_access.delete(\"msm_Project\", \"sim_test\")\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "c99513d8",
"metadata": {},
"outputs": [],
"source": [
"data_access.delete(\"msm_Project\", \"sim_test\")"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "f31060ad",
"metadata": {},
"outputs": [],
Expand Down
19 changes: 19 additions & 0 deletions tests/test_datatable.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import os
from mikeplus import DataTableDemoAccess
from datetime import datetime


def test_opendatabase():
Expand Down Expand Up @@ -68,6 +69,24 @@ def test_manipulate_data():
data_access.delete("msm_Link", "link_test")
muids = data_access.get_muid_where("msm_Link", "MUID='link_test'")
assert len(muids) == 0
field_values = {
"ComputationBegin": datetime(2023, 11, 1, 0, 0, 0, 0),
"ComputationEnd": datetime(2023, 11, 1, 1, 0, 0, 0),
}
data_access.insert("msm_Project", "sim_test", field_values)
fields = ["ComputationBegin", "ComputationEnd"]
values_get = data_access.get_field_values("msm_Project", "sim_test", fields)
assert values_get[0] == datetime(2023, 11, 1, 0, 0, 0, 0)
assert values_get[1] == datetime(2023, 11, 1, 1, 0, 0, 0)
field_values = {
"ComputationBegin": datetime(2023, 11, 1, 1, 0, 0, 0),
"ComputationEnd": datetime(2023, 11, 1, 2, 0, 0, 0),
}
data_access.set_values("msm_Project", "sim_test", field_values)
values_get = data_access.get_field_values("msm_Project", "sim_test", fields)
assert values_get[0] == datetime(2023, 11, 1, 1, 0, 0, 0)
assert values_get[1] == datetime(2023, 11, 1, 2, 0, 0, 0)
data_access.delete("msm_Project", "sim_test")
data_access.close_database()


Expand Down

0 comments on commit 02f6f2f

Please sign in to comment.