beetbox/beets

Update mediafields regression

Chiusa

#5580 aperta il 6 gen 2025

 (0 commenti) (1 reazione) (0 assegnatari)Python (1837 fork)batch import
buggood first issue

Metriche repository

Star
 (12.133 stelle)
Metriche merge PR
 (Merge medio 26g 4h) (51 PR mergiate in 30 g)

Descrizione

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

Guida contributor