mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-01-11 20:00:30 +01:00
DataStack.addStorage failing after first migration #348
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @timfraedrich on GitHub (Oct 20, 2020).
I'm trying to do something like suggested in #276, but as a generalised solution, so I do not have to code it every time something like that comes up. For that I set up some protocols with which I will define my data models.
For normal data models:
and for so called intermediate data models:
I setup my data stack and perform the custom migrations in the following way:
The first run of the loop which sets up the data base up to and including the first intermediate model always succeeds, but for the second it always throws an error saying
The model used to open the store is incompatible with the one used to create the store, even though all required mapping providers and so on are set up correctly.I hope I'm not missing something really obvious, like do I for example have to be aware of anything when reusing the same SQLiteStore without relaunching in between? I couldn't find anything on that in the documentation.
I would appreciate any help, thanks in advance.
@JohnEstropia commented on GitHub (Oct 20, 2020):
@timfraedrich How are you initializing your
DataStack?@timfraedrich commented on GitHub (Oct 20, 2020):
Sorry totally forgot about that code snippet:
I normally do not initialise with a SchemaHistory which might actually be the issue since I wasn't even familiar with it before, but I saw no other way to setup the data stack from an array of schemata.
@JohnEstropia commented on GitHub (Oct 20, 2020):
This looks okay. How are you declaring entities in your
CustomDataModelimplementations?@timfraedrich commented on GitHub (Oct 20, 2020):
They are just normal
CoreStoreObjectswith the addition of a staticidentifierproperty, which shouldn't cause this issue, I have been using it from the start.Also what I totally forgot about: I'm using version 7.3.0, just for reference
@JohnEstropia commented on GitHub (Oct 20, 2020):
I'm just curious how you are initializing your
CoreStoreSchemainstances, particularly theEntity<X>declarations@timfraedrich commented on GitHub (Oct 20, 2020):
Sure, here is an example:
@timfraedrich commented on GitHub (Oct 20, 2020):
Okay so apparently the models were not the issue, I just transitioned from synchronously adding the storage to using the modern CoreStore implementation and adding it asynchronously. For that I used a function which calls itself in case there are elements left to be migrated to:
I also extended
SQLiteStoreto be able to determine which version it has (I did not find any standard implementation for that:The above code now works like a charm, performing intermediate migration actions in between the migrations. Maybe this could in one form or another be implemented into CoreStore itself, as pointed out in the above referenced issue this functionality is missing so far and would be a great addition.
I'm still not sure what exactly went wrong here though, maybe its worth looking at dataStack.addStorageAndWait a bit closer.
@JohnEstropia commented on GitHub (Oct 20, 2020):
Okay, so I missed something important in your original code.
Progressive migrations do not work with
DataStack.addSynchronous(...).See: https://github.com/JohnEstropia/CoreStore#starting-migrations
Since you have multiple steps in your migration, lightweight migration will not work, so you are getting the model mismatch error as intended.
If you use the asynchronous method
DataStack.addStorage(...)instead, you'll get this behavior for free:https://github.com/JohnEstropia/CoreStore/blob/develop/Sources/DataStack%2BMigration.swift#L488
@timfraedrich commented on GitHub (Oct 20, 2020):
I'm not quite sure we are talking about the same thing, when using the asynchronous method one could theoretically layer migrations, but this is not done automatically as I suggested.
It was just a suggestion though, maybe it's too complicated to incorporate into the CoreData logic.
@JohnEstropia commented on GitHub (Oct 20, 2020):
It is automatic. Note that the
exactCurrentModelVersionargument is optional. If you don't pass it explicitly CoreStore will use the final version in theMigrationChain, as long as there is only one possible final version.@timfraedrich commented on GitHub (Oct 20, 2020):
Yes of course, and it is really well thought out, but I am talking about the actions performed in between migrations. Sorry I think I was not very clear on that aspect.
@JohnEstropia commented on GitHub (Oct 20, 2020):
I see, I thought you were talking about the
currentModelfunction. I'm curious what specific processing you do in-between migrations though. Since something like yourintermediateMappingActionsis entirely up to the developer (ex: it might be asynchronous), I'm not sure we can keep a standard API that is simpler than calling your own recursive method onaddStorage(...).On another note, one thing I'd recommend is to use
DataStack. requiredMigrationsForStorage(...)to get the precomputed steps. Once you have those steps you can create temporaryDataStacks that uses a partialMigrationChainthat migrates one step at a time. It's similar to yoursetup()method, but with less code for computing steps.You might be interested to look at the Demo app's
⭐️Advanced.EvolutionDemo.Migrator.swiftfile if you haven't yet. That demo allows both two-way migrations, as well as supporting actual use of multiple model versions at any given time.@timfraedrich commented on GitHub (Oct 20, 2020):
Well in my particular case I am combining two objects with a relationship to another into one while retaining said relationship. I hope I can finish the first part of the migration today, since my project is open-source I could post a reference to the commit here, if you like.
Regarding the implementation of a standard API you're probably more qualified to judge this, I might look at a possible solution incorporating only existing CoreStore implementations in the future though, I will obviously create a post request once I have figured anything out, let's see.
Thanks for pointing out the example project, I actually haven't had a look at that specific one!
@JohnEstropia commented on GitHub (Oct 21, 2020):
Thanks for the feedback! Please do share if you have implementations that may be good reference of use cases