Skip to content

Enhance db.OnConflictOpts #346#456

Merged
ebrahimebrahim merged 2 commits into
OpenwaterHealth:mainfrom
samueljwu:on-conflict-string-options
May 25, 2026
Merged

Enhance db.OnConflictOpts #346#456
ebrahimebrahim merged 2 commits into
OpenwaterHealth:mainfrom
samueljwu:on-conflict-string-options

Conversation

@samueljwu
Copy link
Copy Markdown
Contributor

Summary

  • Allow db.write_* / delete methods to accept string on_conflict values: "error", "overwrite", and "skip", case-insensitive
  • Keep backwards compatibility with OnConflictOpts

Fixes #346

Testing

  • Added coverage for enum and string conflict options, including case-insensitive strings

All existing tests pass
Pre-commit hooks pass

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves the ergonomics of the database write/delete APIs by allowing on_conflict to be passed as a case-insensitive string ("error", "overwrite", "skip") while preserving support for the existing OnConflictOpts enum.

Changes:

  • Replaced the previous dynamically-created OnConflictOpts with a str-backed enum and added _normalize_on_conflict() to accept/validate string inputs.
  • Normalized on_conflict at the start of multiple Database.write_* / delete_* methods to enable case-insensitive string options.
  • Added tests covering enum usage and string usage (including mixed-case strings) plus invalid string handling.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/openlifu/db/database.py Introduces a string-backed OnConflictOpts and normalizes/validates on_conflict across write/delete entry points.
tests/test_database.py Adds coverage asserting string on_conflict values (case-insensitive) behave equivalently to the enum and invalid strings are rejected.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/openlifu/db/database.py Outdated
Comment on lines +56 to +57
def write_gridweights(self, transducer_id: str, grid_hash: str, grid_weights, on_conflict: OnConflictOpts = OnConflictOpts.ERROR):
on_conflict = _normalize_on_conflict(on_conflict)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@samueljwu agreed with this: updating the signature needed for valid type annotations in the case that someone wants to pass a str. Even though OnConflictOpts now inherits from str, that doesn't address the type annotation: it allows you to pass an OnConflictOpts where a str is expected, but not vice versa.

Copy link
Copy Markdown
Collaborator

@ebrahimebrahim ebrahimebrahim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this, it was bugging me too!

It looks good to me, I would say just address the copilot comment regarding the type annotations and this should be good to go

@samueljwu
Copy link
Copy Markdown
Contributor Author

Makes sense! I've updated the type annotations. Thanks

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

Comment on lines +99 to 101
def delete_user(self, user_id: str, on_conflict: OnConflictOpts | str = OnConflictOpts.ERROR) -> None:
on_conflict = _normalize_on_conflict(on_conflict)
# Check if the user ID already exists in the database
Comment on lines +152 to 154
def delete_protocol(self, protocol_id: str, on_conflict: OnConflictOpts | str = OnConflictOpts.ERROR):
on_conflict = _normalize_on_conflict(on_conflict)
# Check if the sonication protocol ID already exists in the database
Comment on lines 249 to +251
on_conflict: Behavior when session doesn't exist ('error' or 'skip')
"""
on_conflict = _normalize_on_conflict(on_conflict)
Comment thread tests/test_database.py
Comment on lines +97 to +104
def test_on_conflict_accepts_enum_and_strings(example_database: Database):
assert OnConflictOpts.OVERWRITE.value == "overwrite"

protocol = Protocol(name="bleh", id="a_protocol_with_string_conflict_option")
example_database.write_protocol(protocol)

with pytest.raises(ValueError, match="already exists"):
example_database.write_protocol(protocol, on_conflict="ERROR")
@ebrahimebrahim
Copy link
Copy Markdown
Collaborator

(Most of the copilot comments are not issues newly introdueced by this PR. It looks good)

@ebrahimebrahim ebrahimebrahim merged commit 68b00c9 into OpenwaterHealth:main May 25, 2026
10 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.

db.OnConflictOpts is unwieldy

3 participants