beetbox/beets

Update mediafields regression

クローズ

#5,580 opened on 2025/01/06

 (0 件のコメント) (1 件のリアクション) (0 人の担当者)Python (1,837 件のフォーク)batch import
buggood first issue

Repository metrics

Stars
 (12,133 個のスター)
PR merge metrics
 (平均マージ 26d 4h) (30d で 51 merged PRs)

説明

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

コントリビューターガイド