mirror of
https://github.com/beetbox/beets.git
synced 2026-02-18 21:36:35 +01:00
* Move genre-to-genres migration into a dedicated Migration class and wire it into Library._migrations for items and albums. * Add batched SQL updates via mutate_many and share the multi-value delimiter as a constant. * Cover migration behavior with new tests. I initially attempted to migrate using our model infrastructure / Model.store(), see the comparison below: Durations migrating my library of ~9000 items and ~2300 albums: 1. Using our Python logic: 11 minutes 2. Using SQL directly: 4 seconds That's why I've gone ahead with option 2.
54 lines
2 KiB
Python
54 lines
2 KiB
Python
import pytest
|
|
|
|
from beets.library.migrations import MultiGenreFieldMigration
|
|
from beets.library.models import Album, Item
|
|
from beets.test.helper import TestHelper
|
|
|
|
|
|
class TestMultiGenreFieldMigration:
|
|
@pytest.fixture
|
|
def helper(self, monkeypatch):
|
|
monkeypatch.setattr("beets.library.library.Library._migrations", ())
|
|
helper = TestHelper()
|
|
helper.setup_beets()
|
|
|
|
monkeypatch.setattr(
|
|
"beets.library.library.Library._migrations",
|
|
((MultiGenreFieldMigration, (Item, Album)),),
|
|
)
|
|
yield helper
|
|
|
|
helper.teardown_beets()
|
|
|
|
def test_migrates_only_rows_with_missing_genres(self, helper: TestHelper):
|
|
helper.config["lastgenre"]["separator"] = " - "
|
|
|
|
expected_item_genres = []
|
|
for genre, initial_genres, expected_genres in [
|
|
# already existing value is not overwritten
|
|
("Item Rock", ("Ignored",), ("Ignored",)),
|
|
("", (), ()),
|
|
("Rock", (), ("Rock",)),
|
|
# multiple genres are split on one of default separators
|
|
("Item Rock; Alternative", (), ("Item Rock", "Alternative")),
|
|
# multiple genres are split the first (lastgenre) separator ONLY
|
|
("Item - Rock, Alternative", (), ("Item", "Rock, Alternative")),
|
|
]:
|
|
helper.add_item(genre=genre, genres=initial_genres)
|
|
expected_item_genres.append(expected_genres)
|
|
|
|
unmigrated_album = helper.add_album(
|
|
genre="Album Rock / Alternative", genres=[]
|
|
)
|
|
expected_item_genres.append(("Album Rock", "Alternative"))
|
|
|
|
helper.lib._migrate()
|
|
|
|
actual_item_genres = [tuple(i.genres) for i in helper.lib.items()]
|
|
assert actual_item_genres == expected_item_genres
|
|
|
|
unmigrated_album.load()
|
|
assert unmigrated_album.genres == ["Album Rock", "Alternative"]
|
|
|
|
assert helper.lib.get_migration_state("multi_genre_field_items")
|
|
assert helper.lib.get_migration_state("multi_genre_field_albums")
|