beetbox/beets

Update mediafields regression

已关闭

#5,580 创建于 2025年1月6日

 (0 条评论) (1 个反应) (0 位负责人)Python (1,837 个派生)batch import
buggood first issue

仓库指标

星标
 (12,133 个星标)
PR 合并指标
 (平均合并 26天 4小时) (30 天内合并 51 个 PR)

描述

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

贡献者指南