I have started working on an iPhone application that where I need to synchronize data with an external MySQL database. The current database scheme uses GUID/UUID fields as primary keys to maintain relationships between tables. I already have this working between a database app and the MySQL database, so this isn't a question regarding synchronization per say.
I've started going down the path of using Core Data, but I'm realizing that it maintains relationships between entities using it's own schema within the SQLite database.
Am I going down the wrong path using Core Data? If not how does one synchronize data between a Core Data store and an external database and still maintain the data relationships?
All you need to do is write the logic to translate entities from one db schema to another. You can fetch objects from the server and convert them to core data objects, and fetch object from core data and convert them to mysql entities when saving to the server. Nothing too difficult involved really
I agree with Griffo; simply translate the rows or entities you retrieve from the mysql database into managed objects (and visa versa).
If I understand what you are looking to correctly, I would definitely recommend using Core data. Translating the data between MySQL and Core Data isn't that hard, and if you use an NSFetchedResultsController to display your data in a UITableView, you practically don't have to write any code.
and you can always preserve the original GUIDs as, for example, optional externalIDs for the imported entities. This way you will be able troubleshoot your data imports easier and correlated the data between the to types of the data stores.
Related
I understand that Core Data is not a relational database but I need to understand how it can be used to support a client/server model where the server uses a Rails, ActiveRecord, Mysql setup.
My app is pulling records from the server using JSON and I am mapping the relationships using Core Data.
The Foreign Key in the SQLLite database is showing the PK field of the related table even though I have set the User Info Key/Value of primaryAttributeKey => id. (I can't remember where I saw this mentioned.)
Is there any way to setup the models so they will use my id as the PK so that it will clean up the export of related data back to the server?
Edward,
The PK is just a field in your object. If you want to maintain them in CD, they are just numbers. As you build your object graph, you have to maintain them in parallel with your relations. Of course, exporting records created on the device back to your server will have difficulty -- FKs and PKs are unique to each table and that uniqueness is determined on the server. Hence, tracking these numbers is not that useful.
May I suggest that your JSON needs to be structured such that it is redundant -- that it has both the data and the various PKs and FKs, if any?
Finally, you appear to be making a CRUD focused API. Generally, those are low performance APIs for remote devices. There are other problems with CRUD APIs, such as inconsistent business logic between servers and clients. I would suggest you to rethink your APIs.
Andrew
I have a doubt about Core Data migration.
Say I have an application which has some predefined values in a table A. I want to sync it with another database, with a table B in such a way that when new records are added totable B, that record should get added to my table A.
I know using Core Data migration, when I add columns to a table, I will be able to access the values previously stored in the older table before the addition of the column.
I would like to know how my table can be updated with the added records on another table.
Update:
From comment below:
The question I had in mind is this...
I want to release an update for my
app. I'm stuck on how to update the
existing Core Data database which also
stores data entered by the user. All I
need to do is update a couple of
records and preserve current user
data. How do I do this?
Core Data is not SQL. Entities are not tables. Objects are not rows. Columns are not attributes. Core Data is an object graph management system that may or may not persist the object graph and may or may not use SQL far behind the scenes to do so. Trying to think of Core Data in SQL terms will cause you to completely misunderstand Core Data and result in much grief and wasted time.
That way lies madness.
It sounds like you don't actually want to migrate as the term is used in Core Data. Migration in Core Data means moving from an earlier version of a data graph's persistent store to a newer version of the same.
E.g. In the 1.0 version you have an entity Person with the attributes firstNameand lastName. After the app has been release you wish to update to the 2.0 version and add a phoneNumber attribute to the Person entity. You would use migration to update the user's existing object graphs and persistent stores to the new object graph.
If by "table" you actually mean entities, then you can link entities together in a relationship so that they can watch each other. If by "table" you mean a data model or persistent store, then the answer is more complex. It can be done using configurations, fetched attributes, UUIDs etc but you must understand what you really need to do before you jump through all those hoops.
I have a SQLite database. Should I put the DB in a data structure with Core Data. How can I do? My problem is "z relations" between tables.
It's possible?
Core Data isn't SQL even when it employs an SQLite store. Although it is theoretically possible to convert a standard SQLite file to the schema Core Data uses, that is difficult and risky especially given that Apple doesn't document the schema and can therefore change it without warning. You really need to translate the SQL data into Core Data objects.
The best way is to write a utility app containing you Core Data model. Read in the SQL data with the standard functions and then use that data and relationships to create the appropriate managed objects and object relationships in Core Data.
Usually you have code anyway for creating managed objects, populating attributes and setting relationships. Just use that code but instead of providing the data from the UI or a feed, provide it from the data provided by SQL.
I found a solution. In the future, should I use SQLite directly, but for those who have a similar problem to mine this solution works well.
Step 1: Core Data in your table add column headed gl'ID temporary relations of the original table.
Step 2: In the data in CSV add two columns. The first column contains the value 1 and refers to P_OPT of Core Data and the second column contains the identifier of the table and retrieved P_ENT generated by reading the SQLite Core Data in the table Z_PRIMARYKEY.
Step 3: With any editor Mac transfer your data in SQLite files generated by Core Data. Remember to attach gl'ID (relations) in the temporary columns.
Step 4: Through the use of the SQL UPDATE command (works with any SQL editor on the Mac) updates all ID columns of relations in Core Data with the value Z_PK. The value retrieved by the queries and the use of temporary columns.
Sorry for the bad English. I hope not to have been convoluted with the explanation and useful to others.
One thing I have in mind is, that datasets in Core Data (or lets say: managed objects) have no ID like known from other databases such as MySQL. Also, they're not in a specific guaranteed order.
What else makes Core Data much more "special" compared to working with a relational database like MySQL? Besides the whole object graph persisting and ORM stuff?
This is a good article explaining the main differences. The biggy for me is
'Core Data cannot operate on data
without loading the data into memory'
This alone makes core-data and MySQL suited to totally different tasks.
The big difference I would say is that Core Data is built on an ORM, an Object Relational Mapping, while MySQL is just a relational database. You could actually host CoreData on MySQL if Apple wanted to let you. Instead they use a different embedded SQLight solution or an XML representation depending on what you want for your backing store.
Does anyone have any advice on using a datastore with mapkit to provide a database of locations (Restaurants) that are query-able by location?
I would like to use Core data but importing the information into it seems like a project in itself. If anyone has good advice on converting an existing sqlite/cvs file to a coredata sqlite file that would be appreciated.
Is old-fashioned sqlite better than using core data for the task, or is it a case that I should create a web service for the job?
I would like to be able to query the locations based on the map zoom also.
Thanks if you have any advice on the matter.
If you write your object model correctly, you can just point it at an existing sqLite database and it will read it as if core data generated it in the first place.
For example, suppose you have an existing sqlite db of people with columns like firstName, lastName, phone# etc. You just create a core data model with a entity with attributes of firstName, lastName, phone# etc. Spell them the same and make sure they have the right type and then point the NSPersistentStoreCoordinator at the existing database. It will read it in fine.
Core data is always the way to go for any larger data management task. It makes everything so much easier once you learn it.
Edit01:
Never mind the above. I was thinking of Enterprise Objects. Core data won't easily import most existing SQL.
Instead, I would export the sqlite to csv and then use something like cCSVParse to convert to plist. Then you can read it in easily to an array or dictionary and use that to populate the core data db.
That will work easily for db's that don't depend on complex relationships. I think the future benefits of having core data will eventually easily pay for the few man hours spent converting.