Skip to content

Comments

Feature/new api for model database#89

Merged
ryan-kipawa merged 67 commits intomainfrom
feature/new_api_for_model_database
Apr 28, 2025
Merged

Feature/new api for model database#89
ryan-kipawa merged 67 commits intomainfrom
feature/new_api_for_model_database

Conversation

@ryan-kipawa
Copy link
Collaborator

@ryan-kipawa ryan-kipawa commented Mar 20, 2025

A new fluent-like API is introduced in this PR for working with the MIKE+ database.

Main changes:

  • DataTableAccess will be replaced by Database. It's a cleaner implementation with more thorough testing. DataTableAccess would become legacy, but kept around for a while since others are using it.
  • Table classes are autogenerated for each table in the database, which are accessed though a table collection on Database.tables
  • Each table class has a flexible, fluent-like API with select, insert, update, and delete (with various conditions).
  • Each table class has a columns attribute for get an enum of possible column values
  • Conversion logic between .NET pythonnet objects and python has been centralized a bit more

I think this structure will also allow for future extension in an easy way, since it loosely follows the MIKE+ design.

Closes:
#90
#35
#44
#27
#17

Here's a brief comparison of the old vs new API:

Opening database

Old API

data_access = DataTableAccess("model.sqlite")
data_access.open_database()

# Close when done
data_access.close_database()

New API

# Initialize with auto_open=True (the default)
db = Database("model.sqlite")
# Close when done
db.close()

# Or use context manager for automatic open/close
with Database("model.sqlite") as db:
    # Work with database
    pass

Querying Data

Old API

# Get all MUIDs in a table
muids = data_access.get_muid_where("msm_Link")

# Get specific fields for a single record
fields = ["Diameter", "Length", "FromNode"]
values = data_access.get_field_values("msm_Link", "Link_2", fields)

# Get values for all records with a condition
result = data_access.get_muid_field_values("msm_Link", fields, "Diameter > 1.0")

New API

# Access a table through the tables collection
link_table = db.tables.msm_Link

# Get all MUIDs with optional ordering
muids = link_table.get_muids(order_by="Diameter", descending=False)

# Query with chainable methods
result = link_table.select(["Diameter", "Length", "FromNode"]) \
                  .where("Diameter > 1.0") \
                  .order_by("MUID") \
                  .execute()

# Convert to pandas DataFrame
df = link_table.select(["Diameter", "Length"]) \
              .to_pandas()

# Parameterized where statements
min_diameter = 0.5
result = link_table.select() \
                  .where("Diameter > :min_diameter", {"min_dimaeter" : min_diameter}) \
                  .to_pandas()

Inserting Data

Old API

# Insert a new record
values = {
    'Diameter': 2.0, 
    'Description': 'New pipe', 
    'geometry': "LINESTRING (3 4, 10 50, 20 25)"
}
data_access.insert("msm_Link", "new_link_1", values)

New API

# Insert using chainable methods
db.tables.msm_Link.insert({
    "MUID" : "new_link_1",
   "Diameter" : 2.0,
    "Description" : "New pipe",
    "geometry" : "LINESTRING (3 4, 10 50, 20 25)"
})

# Or auto-generate the MUID
db.tables.msm_Link.insert({
    "Diameter" : 2.0,
    "Description" : "New pipe",
    "geometry" : "LINESTRING (3 4, 10 50, 20 25)"
})

Deleting Data

Old API

# Delete a record
data_access.delete("msm_Link", "Link_2")

New API

# Delete using chainable methods
db.tables.msm_Link.delete() \
    .where("MUID = 'Link_2'") \
    .execute()

# Safety feature - to delete all records, must explicitly call all()
db.tables.msm_Link.delete() \
    .all() \
    .execute()

@ryan-kipawa ryan-kipawa force-pushed the feature/new_api_for_model_database branch from 6dc8fdf to 69ca8e7 Compare April 9, 2025 11:01
@ryan-kipawa ryan-kipawa merged commit f9f18e1 into main Apr 28, 2025
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants