-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Convert flexible field values to SQL before storing them #5833
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
base: master
Are you sure you want to change the base?
Conversation
Thank you for the PR! The changelog has not been updated, so here is a friendly reminder to check if you need to add an entry. |
There was a problem hiding this 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 adds conversion of flexible field values to their SQL representation before inserting them into the database, enabling support for multivalued flexible fields.
- Applies
to_sql
on each flexible field value prior to storage. - Removes keys from the dirty set as before, then converts and inserts the SQL value.
- (To be added) Changelog and tests for the new behavior.
Comments suppressed due to low confidence (2)
beets/dbcore/db.py:607
- [nitpick] Overwriting the original
value
variable may reduce readability; consider assigning the converted value to a new variable (e.g.,sql_value
) and using that in themutate
call.
value = self._type(key).to_sql(value)
beets/dbcore/db.py:607
- Add tests to cover the new
to_sql
conversion path for flexible fields, verifying that multivalued and edge-case values produce the expected SQL representations.
value = self._type(key).to_sql(value)
I'm having a hard time writing tests for this. It looks like my types aren't getting registered: diff --git a/test/test_plugins.py b/test/test_plugins.py
--- a/test/test_plugins.py (revision 40d83b5b32b313d8dd7a13a1ed989b3760fdacdd)
+++ b/test/test_plugins.py (date 1751198533085)
@@ -94,6 +94,17 @@
out = self.run_with_output("ls", "rating:3..5")
assert "aaa" not in out
+ def test_multi_value_flex_field_type(self):
+ class MultiValuePlugin(plugins.BeetsPlugin):
+ item_types = {"multi_value": types.MULTI_VALUE_DSV}
+
+ self.register_plugin(MultiValuePlugin)
+ assert plugins.types(Item) is not None
+
+ item = Item(path="apath", artist="aaa")
+ item.multi_value = ["one", "two", "three"]
+ item.add(self.lib) # throws an error
+
class ItemWriteTest(PluginLoaderTestCase):
def setUp(self): Any ideas? |
@snejus, did you have a chance to look into this already? |
Yes, I finally have! You've uncovered a fundamental issue with how we register types and queries provided by plugins, which makes it nearly impossible to test properly. I've just opened a PR with a fix. You can try to rebase on top of it and try testing again :) |
Thank you so much! Seems to work now. I'll finish my tests and push everything when it's done. |
## Fix dynamic plugin type and query registration This PR refactors the plugin system to properly handle dynamic type and query registration by converting static class attributes to cached class properties. **Problem**: Plugin types and queries were stored as mutable class attributes that were manually updated during plugin loading/unloading. This caused issues where: - Plugin types weren't properly registered in test environments - Shared mutable state between test runs caused inconsistent behavior - Manual cleanup was error-prone and incomplete See #5833 and specifically #5833 (comment) for the context. **Solution**: - Convert `_types` and `_queries` from static dictionaries to `@cached_classproperty` decorators - Types and queries are now dynamically computed from loaded plugins when accessed - Eliminates manual mutation of class attributes during plugin loading - Properly clears cached properties when plugins are loaded/unloaded - Ensures plugin types are available immediately after registration **Key Changes**: - `Model._types` and `LibModel._queries` now use `@cached_classproperty` - Removed manual `_types.update()` calls in plugin loading code - Added proper cache clearing in test infrastructure - Plugin types are now inherited through the class hierarchy correctly This fixes the developer's issue where `item_types` weren't being registered properly in tests - the new dynamic property approach ensures plugin types are available as soon as plugins are loaded.
@Maxr1998 it's been merged into |
This is required to support multivalued fields as flexible fields.
40d83b5
to
21d03a7
Compare
@snejus thank you so much for fixing it! Just rebased again and pushed my test. |
Codecov ReportAll modified and coverable lines are covered by tests ✅
🚀 New features to boost your workflow:
|
21d03a7
to
8db661b
Compare
Description
This is required to support list values in flexible fields.
See #5698 for more details.
To Do
docs/changelog.rst
to the bottom of one of the lists near the top of the document.)