Repository metrics
- Stars
- (12,133 stars)
- PR merge metrics
- (Avg merge 9d 12h) (46 merged PRs in 30d)
Description
Problem
I created a plugin to read/write additional tags from a file as per https://beets.readthedocs.io/en/stable/dev/plugins.html#extend-mediafile, e.g.
class FooPlugin(BeetsPlugin):
def __init__(self):
field = mediafile.MediaField(
mediafile.MP3DescStorageStyle(u'foo'),
mediafile.StorageStyle(u'foo')
)
self.add_media_field('foo', field)
Executing an update as beet up fails with the following traceback:
Traceback (most recent call last):
File "/home/peter/bin/beet", line 8, in <module>
sys.exit(main())
^^^^^^
File "/mnt/code/beets/beets/ui/__init__.py", line 1870, in main
_raw_main(args)
File "/mnt/code/beets/beets/ui/__init__.py", line 1849, in _raw_main
subcommand.func(lib, suboptions, subargs)
File "/mnt/code/beets/beets/ui/commands.py", line 1745, in update_func
update_items(
File "/mnt/code/beets/beets/ui/commands.py", line 1697, in update_items
item.store(fields=item_fields)
File "/mnt/code/beets/beets/library.py", line 396, in store
super().store(fields)
File "/mnt/code/beets/beets/dbcore/db.py", line 608, in store
tx.mutate(query, subvars)
File "/mnt/code/beets/beets/dbcore/db.py", line 985, in mutate
cursor = self.db._connection().execute(statement, subvals)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
sqlite3.OperationalError: no such column: foo
Digging down into this problem leads me to the following commit: https://github.com/beetbox/beets/commit/acff509585eacc4c4735cedf725ba33bcf17ceab
- item_fields = fields or library.Item._fields.keys()
+ if fields is None:
+ # no fields were provided, update all media fields
+ item_fields = fields or library.Item._media_fields
The commit makes the assumption that if no fields are given, all fields in library.Item._media_fields should be updated.
Fields in library.Item._media_fields can be both fixed or flex.
This escalates a bit later in the same function where item.store(fields=item_fields) is called.
Its implementation https://github.com/beetbox/beets/blob/801bac5f9e3af59c68bb09e9b5b552a260c3d337/beets/dbcore/db.py#L577
seems to assume that field only contains fixed fields and tries to update a flex as if it is a fixed.
Solution
Partially rolling back commit https://github.com/beetbox/beets/commit/acff509585eacc4c4735cedf725ba33bcf17ceab by assuming all fields from library.Item._fields.keys() must be included solves the problem. I'll create PR for that.
However, I think the real issue is in the dbcore.db.Model.store() implementation
Setup
- OS: Manjaro Linux
- Python version: 3.12.7
- beets version: v2.2.0
- Turning off plugins made problem go away (yes/no): no