beetbox/beets

Update mediafields regression

Fermée

#5 580 ouverte le 6 janv. 2025

 (0 commentaire) (1 réaction) (0 personne assignée)Python (1 837 forks)batch import
buggood first issue

Métriques du dépôt

Stars
 (12 133 étoiles)
Métriques de merge PR
 (Merge moyen 26j 4h) (51 PRs mergées en 30 j)

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

Guide contributeur