I need to have 2 separate data bases on my project, so my question is, how can I have more than 1 CoreData data base on the same project? Im asking this since I already have one coredata data base setup.
I would be very thankful if I could have an explanation or a tutorial/example on how to address this problem.
To create multiple Core Data stores, you make a separate xcdatamodel schema for each of the data stores. In your application, you need to choose how you separate Core Data "stacks" for each of these schemata:
you could have separate NSManagedObjectModel instances, one for each schema; or you could create a merged model that contains the objects from both schemata.
you'll need at least one NSPersistentStore and NSPersistentStoreCoordinator for each managed object model - for most practical uses this means either one per model or a single store if you're using a merged model.
you then create NSManagedObjectContext instances as you need them, backed by the persistent store coordinator(s).
However, this is iOS, so users of your application will probably never manage or care about how your data stores are organised. Unless you have a technical reason not to, you will find things easier just to define all of your entities in a single Core Data model.
Related
I am facing same problem as here
How to achieve relationships between entity in one store with other?
Kindly guide me through this.
It is indeed possible and makes total sense in some cases to split objects across stores
lets assume obj A in Store #1 and obj B in Store #2.
Each A has N Bs
easiest solution would maybe be a TRANSIENT property on A ... named 'allMyBs'
then implement the fetch in code:
- (NSArray*)allMyBs {
NSFetchRequest *r == ... //setup to fetch Entity B
[CoreDataHelper managedObjectContextForStore2] executeFetchRequest:r];
}
this isnt the fetched property yet but easy
see Cross-Store weak relationship with Fetched Properties? for a complicated way ^^
The short answer is that you can't. You can't have a relationship between managed objects that crosses persistent stores.
You can, however, implement a key or identifier in your model that YOU maintain across stores, and use that find 'related' objects in different stores.
If you have user records in one store, and application data in another, the application records might have a "belongsTo" property whose value is a user ID corresponding to a user record in the user store.
Apple's documentation is very specific about this:
From the Core Data Programming Guide:
"Core Data does not let you create relationships that cross stores. If you need to create a relationship from objects in one store to objects in another, you should consider using fetched properties."
Again, from the Core Data Programming Guide:
"You must be careful not to create relationships from instances in one persistent store to instances in another persistent store, as this is not supported by Core Data. If you need to create a relationship between entities in different stores, you typically use fetched properties (see “Fetched Properties”)."
This is exactly what I am talking about above. If you implement fetched properties that way, it is up to you to maintain the integrity of the graph. The same document walks you through creating and using fetched properties. Perhaps you can be more specific in what you need answered.
Can Core Data allow me to create new table programmatically? or if I need that I need to use SQLite directly.
thanks
From a CoreData perspective, you don't really create new tables because database tables are only one possible type of persistence store associated with the core data model.
You can, however, create new core data entities programatically using the NSEntityDescription class. In the NSEntityDescription class documentation you will find this:
Entity descriptions are editable until they are used by an object graph manager. This
allows you to create or modify them dynamically. However, once a description is used
(when the managed object model to which it belongs is associated with a persistent store
coordinator), it must not (indeed cannot) be changed. This is enforced at runtime: any
attempt to mutate a model or any of its sub-objects after the model is associated with a
persistent store coordinator causes an exception to be thrown. If you need to modify a
model that is in use, create a copy, modify the copy, and then discard the objects with
the old model.
I've never tried to modify one at runtime, so I'm not sure exactly how well this works when you have an existing SQLite persistence store, if at all. But it's probably worth playing around with NSEntityDescription to see if it gets you close to what you are trying to do.
You typically create the managed object model graphically using Xcode's Data Model Design tool. (If you wish you can construct the model programmatically at runtime
Core Data programming Guide
You can however:
Create a Object Model Context (outside of the current one you are in/using)
Create one or more Entities
Create a SEPARATE persistent store for that model
Save entities etc...
Close the store when you're done
You can't change models on the fly as they are pretty much fixed when they're pulled into the runtime environment.
Hello fellow stackoverflow family members?
I know it is un-efficient to create one extra sqlite table in iPhone CoreData system. (X)
Currently, My app has one sqlite table but there are preset data to users to no need to waste parse time. But if I adding new entity in current structure of SQLite table, it wipes up the whole preset data. I haven't tried to use immigrate method but I don't think it wouldn't be just adding a new entity on the table. I'm thinking it also wipes up previous preset data.
Current Architecture of SQLite file.
entity : A
attributes : contains data
I want to keep A with attributes still contain data but also add new entity : B.
entity : A
attributes : previous contained data
(PLUS+)
entity : B
attributes : new data
Do I need to create extra persistence set to separately store entity B (create another SQLite file and use as storage) or Is there possible way to add entity B in current SQLite with no changes in entity A?
Thank you.
To directly answer your question: Yes, you can reference multiple SQLite files in Core Data. You'll want to use a unique persistent store for each one.
I don't understand the rest of your question though, so it may be likely that creating multiple persistent stores is not what you want at all.
I know it is in efficient to create one extra sqlite table in iPhone CoreData system.
This is untrue. Creating multiple entities (aka, tables, but that is abstracted away) can lead to much more efficient queries.
Currently, My app has one sqlite table but there is no need to change preset sqlite table but want to add some other attribute.
Just add the attribute to your entity. If your app has already been released or you want to maintain existing data, you'll have to set up a migration and/or turn on lightweight migration.
So commit with new attribute and update coredata is not valid. Because it flash off current data set and need to spend another hours to type manually.
This didn't make any sense to me. Can you clarify?
I'm building an iPad application where I need user to create entity dynamically. I'm already having 3 entities which program uses.
Could you help me with code how to do it?
I want to understand the whole structure according to my understanding I have to create new managedObjectModel, add new entities and than merge it with existing one, is it correct?
While it is possible to create a new entity and a new model on the fly in practice this is massively complex. If nothing else you would have to migrate any existing persisted data to the new model and a new persistent store file. I strongly recommend against attempting this especially if you are just starting out with Core Data.
You do have options:
Firstly, are you sure you actually need a new entity? People just starting out with Core Data often mistake entities for managed objects. Entities are to managed objects as classes are to instances. Entities are abstractions used to create the object graph. They don't actually contain data. The times when you need new entities are very,very rare.
Secondly, if you do need some kind of dynamic entity, it would usually be best to decompose the dynamic entity into numerous fixed subentities and then use relationships to create a virtual entity. E.g. you need a dynamic Person "entity" so you create several entities in the model each of which holds one attribute of the person. You could have a Field entity which would have a fieldName attribute and then a fieldValue attribute. Then have a an actual Person entity that has no attributes but just relationships to the necessary Field objects. You could add any fields needed to any person and then reconstitute an virtual person object by walking the relationships to its fields.
I rather doubt however that you need that kind of flexibility. Such a need is very rare. I would step back and see exactly what dynamic data you think the user might need to enter.
That's correct -- you'd create an array of NSEntityDescription objects, then call setEntities: on the new managed object model. Then, finally, you'd merge that model with your built-in model.
But note that you can't change a model once it has been used to create a managed object context (or used for storage). You'll need to create new storage and context after the model is changed.
I have an iPhone Core Data app with a pre-populated sqlite "baseline" database. Can I add a second smaller sqlite database with the same tables as my pre-populated "baseline" database but with additional / complementary data such that Core Data will happily union the data from both databases and, ultimately, present to me as if it was all a single data source?
Idea that I had is:
1) the "baseline" database never changes.
2) I can download the smaller "complementary" sqlite database for additional data as and when I need to (I'm assuming downloading sqlite database is allowed, please comment if otherwise).
3) Core Data is then able to union data from 1 & 2. I can then reference this unified data by calling my defined Core Data managed object model.
Hope this makes sense.
Thanks in advance.
Core Data is designed to handle multiple data files via the – addPersistentStoreWithType:configuration:URL:options:error: method. This will allow you to combine all of the data files together and then access them via a single NSManagedObjectContext.
Your only issue, and it may not even be an issue for you, is that the store files cannot directly reference each other. Therefore you will need to reference data between files "manually" via unique identifiers. However I suspect you are already aware of that limitation.
Manual Relationships
The idea is that when both objects in a "relationship" are in one model and one file, Core Data does its magic and handles all of the referential integrity for you. However when they are in different files and/or models this doesn't happen automatically anymore.
The solution to this issue is to use a fetched property that looks up some unique identifier to retrieve the entity (or entities) that you want to be on the other side of the relationship. This will give you a "weak" relationship between files.
One thing to note though when doing this. The fetched property does not get updated automatically when something changes. This means when data changes that would cause that relationship to change, your application will not be automatically made aware of it and you will need to request that property again to get the updated relationship information.
Hopefully that makes it a bit clearer.
Co-existance of fetched properties and relationships
They can definitely co-exist but realize that they are two separate properties. If you want your controller code to see them as one, then I would suggest building a subclass for that entity and then adding a convenience method in there that hits both the relationship and the fetched property and then rolls them up into one NSArray or NSSet before returning it back to your controller code.
You can attach the downloaded database with ATTACH DATABASE statement and operate with unions of tables.