0

Core Data Batch insert

Updated:28.11.2022 20:24 (at the end of this post)

i have 150 rows from entity #1 now i need to insert for each single row from entity #1 (SingleOnes) 20 rows into entity #2 (Packs)

pattern:

row1: count 1, object 1 row2: count 2, object 1 row3: count 3, object 1 (...) row21: count 1, object 2 row22: count 2, object 2 row23: count 3, object 2 and so on 

at the moment i can only do this with creating an array of objects for entity #2 (3000 rows), and save them simply with context.save()

 // sOne:[SingleOnes] // fetched rows from SingleOnes entity // create Packs sOne.forEach { one in for x in 1...20 { let newPack = Packs(context: context) newPack.count = Int16(x) newPack.addToUsedSingleOnes(one) } } context.performAndWait { do { try context.save() } catch let error { print(error.localizedDescription) } } 

but as i have doubts about the reliability of this method i rather want to insert those 3000 rows with a batch insert instead, and i cannot find the right way to do so..

i hand over an array to this function containing all objects from entity #1

 func newBatchInsertSWRequest(with singleOnes: [SingleOnes]) -> NSBatchInsertRequest { var index = 0 let total = singleOnes.count // this is the wrong count and it does not work withs singleOnes.count*20 as well let batchInsert = NSBatchInsertRequest( entity: Packs.entity()) { (managedObject: NSManagedObject) -> Bool in guard index < total else { return true } for x in 1...20 { if let newPack = managedObject as? Packs { let data = singleOnes[index] newPack.count = Int16(x) newPack.addToUsedSingleOnes(data) // (...) } } index += 1 return false } return batchInsert } 

i've tried to many variants of this function but i never managed to create the correct amount of 3000 rows.. any ideas?

Updated:28.11.2022 20:24

 func newBatchInsertWPRequest(with singleOnes: [SingleOnes]) -> NSBatchInsertRequest { var index = 0 let total = 3000 let batchInsert = NSBatchInsertRequest( entity: Packs.entity()) { (managedObject: NSManagedObject) -> Bool in guard index < total else { return true } for x in 1...20 { if let newPack = managedObject as? Packs { let data = singleOnes[index] newPack.count = Int16(x) newPack.addToUsedSingleOnes(data) } index += 1 } return false } return batchInsert } 
Terminating app due to uncaught exception 'NSRangeException', reason: '*** __boundsFail: index 150 beyond bounds [0 .. 149]' terminating with uncaught exception of type NSException 

seems like i can't do it this way...the function expects the amount to be the count of the array given...

i will have to give an array with all 3000 objects to that function.. hm..

7
  • Seems like the first thing to check would be why you're getting a bad value for total (as your code comment mentions). That comes from the argument you pass in, so it's external, but your batch request depends on it. Commented Nov 28, 2022 at 1:06
  • yea that's one of two places i worked on..if i just use: ``` let total = singleOnes.count ``` then i end up with exactly 150 rows inside the Pack entity..so then i took a look at the ``` NSBatchInsertRequest ``` section, and tried to put this whole section into my "for" loop, but this did not work as well..it seems like i understood something wrong here...to make it clear i inserted those 150 singleOnes rows into entity SingleOnes, with a batch insert and had no trouble at all, but there i had a struct to work with, which i don't have here.. Commented Nov 28, 2022 at 7:17
  • maybe the fact that i do have a relationship in each object is the real issue? i might have read something like this...but how do i import 3000 objects with relationships other than the just create and save() ? Commented Nov 28, 2022 at 20:10
  • 1
    I'm not sure but it's true that a batch insert doesn't handle relationships. You would need to either create them individually and save, or else do a batch insert and set up the relationships afterward. Commented Nov 29, 2022 at 1:43
  • 1
    I don't know why it would be less reliable on a device. Commented Nov 29, 2022 at 21:49

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.