I've created a new model and renamed 2 fields of an entity. This entity was never used in the previous app version, so I didn't map it to the new updated entity in the database. Consequently the mapping is not mapping anything new, but the migration is very slow (3 seconds for approximately 50 rows in the main table.). I'm wondering if core data is creating a new database and deleting the older one, and reinserting all data. This is the migration log file: http://cl.ly/3H1v252R1p1c
ps. If NSInferMappingModelAutomaticallyOption
is YES, does this mean that I can potentially experience data losses, since the mapping is improvised by core data ?
thanks
Can you show us your database schema? My guess is that you've used object inheritance in it liberally.
Core Data implements inheritance in SQL stores by creating a single table for the parent entity and adding columns for union of all fields used by child entities. So you may think you've renamed only two fields on one entity but Core Data has to apply changes to every object that inherits from that entity or which has a common ancestor of that entity.
In your specific schema it looks like you have an entity, Item, from which at least Genre, AudioTrack, Studio, Director, Store, Movie, Condition, Region, Owner, AspectRatio, Year, MyRating, Episode, Edition, Format, Producer, Writer, AudienceRating, SeenIt and Movie descend. There may be others as I read your log by eye rather than analysing it automatically. So Core Data creates one table named Item into which every instance of every one of those entities is stored. Whenever any of those entities (or the others I've possibly not found) changes, Core Data has to update the records for all instances of every one of those entities.
That's why you see:
CREATE TABLE ZITEM ( Z_PK INTEGER PRIMARY KEY, Z_ENT INTEGER, Z_OPT INTEGER,
ZUNIQUEID INTEGER, ZCOLLECTIONSTATUS INTEGER, ZHASCOVER INTEGER, ZINDEX INTEGER,
ZPLOTNOTE INTEGER, ZUSERVALUES INTEGER, ZPURCHASEDATEDAY INTEGER,
ZPURCHASEDATEMONTH INTEGER, ZPURCHASEDATEYEAR INTEGER, ZRELEASEDATEDAY INTEGER,
ZRELEASEDATEMONTH INTEGER, ZRUNTIME INTEGER, ZVIEWINGDATEDAY INTEGER,
ZVIEWINGDATEMONTH INTEGER, ZVIEWINGDATEYEAR INTEGER, ZAUDIENCERATING INTEGER,
ZCONDITION INTEGER, ZEDITION INTEGER, ZFORMAT INTEGER, ZLOANER INTEGER,
ZLOCATION INTEGER, ZMYRATING INTEGER, ZOWNER INTEGER, ZSEARCH INTEGER,
ZSEENIT INTEGER, ZSEENWHERE INTEGER, ZSERIES INTEGER, ZSTORAGEDEVICE INTEGER,
ZSTORE INTEGER, ZYEAR INTEGER, ZRANK INTEGER, ZTYPEID INTEGER,
ZCOLLECTIBLE INTEGER, Z3_COLLECTIBLE INTEGER, ZBIN INTEGER, ZSORTORDER INTEGER,
ZSECTION VARCHAR, ZCLZID VARCHAR, ZCONNECTHASH VARCHAR, ZSORTTITLE VARCHAR,
ZTITLE VARCHAR, ZACTORS VARCHAR, ZCLZMEDIAID VARCHAR, ZCURRENTVALUE VARCHAR,
ZIMDBNUMBER VARCHAR, ZIMDBRATING VARCHAR, ZLOANDATE VARCHAR, ZLOANDUEDATE VARCHAR,
ZPURCHASEPRICE VARCHAR, ZSTORAGESLOT VARCHAR, ZTITLEEXTENSION VARCHAR,
ZUPC VARCHAR, ZTHEDESCRIPTION VARCHAR, ZURL VARCHAR, ZDISPLAYNAME VARCHAR,
ZSORTNAME VARCHAR )
That's the table containing the union of all fields of all descendants of Item. It's also why e.g. a fetch for AudienceRatings is executed as:
SELECT t0.Z_ENT, t0.Z_PK, t0.Z_OPT, t0.ZSECTION ... FROM ZITEM t0 WHERE t0.Z_ENT = ?
So:
Core Data on iOS uses SQLite for data storage. SQLite doesn't support ALTER COLUMN
, so Core Data works around this limitation by:
There's a good SO answer here which describes this in a bit more detail.
I've never seen any issues with Core Data losing data while performing this operation - I would assume Apple have implemented safeguards to prevent this, but it's probably worth getting in touch with Apple DTS directly to confirm.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With