Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Editing date and timestamp values #79

Merged
merged 1 commit into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading