Skip to content

Allow to pickle db models by removing the current connection. #5641

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Apr 15, 2025

Conversation

semohr
Copy link
Contributor

@semohr semohr commented Feb 21, 2025

Description

This might be a quick one, depending on how you feel about it... It allows you to pickle DB model objects. I don't think this is used directly in Beets, but it might be useful in general. For instance, we encountered an issue where we wanted to quickly pickle an Item or Album. This sometimes worked and other times failed, which seemed quite inconsistent.

Some DB model methods and properties have the side effect of attaching an SQLite connection to self (._db), which prevents serialization. The fix is quite straightforward, so I thought we might want to integrate this into beets directly.

To Do

  • Changelog
  • Tests

Copy link

Thank you for the PR! The changelog has not been updated, so here is a friendly reminder to check if you need to add an entry.

@snejus snejus requested a review from Copilot April 14, 2025 18:17
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot reviewed 2 out of 3 changed files in this pull request and generated no comments.

Files not reviewed (1)
  • docs/changelog.rst: Language not supported
Comments suppressed due to low confidence (1)

beets/dbcore/db.py:725

  • [nitpick] Consider removing the '_db' key using 'del state["_db"]' instead of setting it to None, to ensure it is fully excluded from the pickled state.
state["_db"] = None

@wisp3rwind
Copy link
Member

Not sure how I feel about this, given that beets doesn't require it directly. Of how much help would it be for a project that uses beets as a library to have this upstream?

Note that a related issue led to the implementation of Model.copy: #2668

@wisp3rwind wisp3rwind added the needinfo We need more details or follow-up from the filer before this can be tagged "bug" or "feature." label Apr 14, 2025
@semohr
Copy link
Contributor Author

semohr commented Apr 14, 2025

We need this for serialization at the moment and patch it manually. I thought this is an easy enhancement without too many tradeoffs and maybe some other people might find it useful.

This fix allows us to do a fully statefull import where we can continue at any point on a standard beets import. Quite usefully for our project.

Currently we do the following:

match: BeetsAlbumMatch | BeetsTrackMatch

# Remove db from all items as it can't be pickled
# FIXME: this should go into beets __getstate__ method
# see https://github.com/beetbox/beets/pull/5641
if isinstance(match, BeetsAlbumMatch):
    for item in match.mapping.keys():
        item._db = None
        item._Item__album = None
    for item in match.extra_items:
        item._db = None
        item._Item__album = None

Just doing pickle.dump(match) would be a bit easier ;)

Copy link
Member

@wisp3rwind wisp3rwind left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough, I'd say this can be merged. Whether or not pickling (rather than actually consistently persisting import state to the db, maybe with a flexible attribute saying that it's incomplete) is the best solution to your original problem might be a different issue. Having pickle support seems generally in line with the vision that the dbcore module should be as generic and reusable as possible, rather than being specific to beets data model.

I think the test should go to test/dbcore.py, however. Would you mind moving it there?

@wisp3rwind wisp3rwind added feature features we would like to implement and removed needinfo We need more details or follow-up from the filer before this can be tagged "bug" or "feature." labels Apr 15, 2025
@semohr
Copy link
Contributor Author

semohr commented Apr 15, 2025

We are actually storing the pickled value in a database 😁 It is quite hacky but any other solution would come with a pile of other issues which tbh wasn't worth the time for us right now.

Copy link
Member

@wisp3rwind wisp3rwind left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

@wisp3rwind wisp3rwind merged commit b4a634a into beetbox:master Apr 15, 2025
16 checks passed
peterjdolan pushed a commit to peterjdolan/beets that referenced this pull request Apr 21, 2025
…x#5641)

## Description

This might be a quick one, depending on how you feel about it... It
allows you to pickle DB model objects. I don't think this is used
directly in Beets, but it might be useful in general. For instance, we
encountered an issue where we wanted to quickly pickle an Item or Album.
This sometimes worked and other times failed, which seemed quite
inconsistent.

Some DB model methods and properties have the side effect of attaching
an SQLite connection to self (._db), which prevents serialization. The
fix is quite straightforward, so I thought we might want to integrate
this into beets directly.

## To Do

- [x] Changelog
- [x] Tests
JOJ0 pushed a commit to JOJ0/beets that referenced this pull request Jun 9, 2025
…x#5641)

## Description

This might be a quick one, depending on how you feel about it... It
allows you to pickle DB model objects. I don't think this is used
directly in Beets, but it might be useful in general. For instance, we
encountered an issue where we wanted to quickly pickle an Item or Album.
This sometimes worked and other times failed, which seemed quite
inconsistent.

Some DB model methods and properties have the side effect of attaching
an SQLite connection to self (._db), which prevents serialization. The
fix is quite straightforward, so I thought we might want to integrate
this into beets directly.

## To Do

- [x] Changelog
- [x] Tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature features we would like to implement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants