Is there a way to change the Data Type in Realm Database?

1.6k views Asked by At

As you can see the image, I totally mess up the Data Type (The red circle). Is there a way to change the Data Type into Integer?

EDIT

I want to change the data type from a String to an Int and I have existing data so I can't start with a fresh realm and just change the var type.

class Item: Object {
    @objc dynamic var name: String?
    @objc dynamic var itemid: String?
    @objc dynamic var cateid: String?
}

enter image description here

2

There are 2 answers

2
Jay On BEST ANSWER

I may have misunderstand the question but you appear to have existing data stored as as a String and you want to 'convert' all of those to an Int.

You cannot directly change the type to another type and have the stored data changed as well. If you do, it will be flagged with an error.

Error!
  Migration is required due to the following errors:
- Property 'Item.itemid' has been changed from 'string' to 'int'.

You need to incorporate a migration block to 'convert' the string value to an Int. Assuming we add a new Int property to our object `item_id', something along these lines will migrate your strings to int's and in the case where the string is not a valid it, it will be assigned a value of 0

Realm.Configuration.defaultConfiguration = Realm.Configuration(
schemaVersion: 1,
migrationBlock: { migration, oldSchemaVersion in
    if (oldSchemaVersion < 1) {
        migration.enumerateObjects(ofType: Item.className()) { oldObject, newObject in
            let stringValue = oldObject!["itemid"] as! String
            newObject!["item_id"] = Int(stringValue) ?? 0
        }
    }
})

Also, as soon as Realm is accessed, the object models are written to the Realm file. So a simple matter of

let items = realm.object(Item.self)

Will store that model even if no data was ever written. If, after that line, the var type is changed from a String to an Int, it will throw the migration error.

Deleting the Realm and starting from scratch is one option if that's the case, and as mentioned above, a migration block.

If this is brand new model that has never been used, then as the comments and other answer suggest, just change the String to an Int.

0
lajosdeme On

Simply change the String to Int in your Object model. Please note that the Realm documentation says:

String, NSDate, and NSData properties can be declared as optional or non-optional using the standard Swift syntax.

So unlike the String in your previous model, you will not be able to declare your Int as optional. You have two options:

  1. Declare a default value:

    class Item: Object {
       @objc dynamic var name: String?
       @objc dynamic var itemid: Int = 0
       @objc dynamic var cateid: Int = 0
    }
    
  2. Declare it as a RealmOptional:

    class Item: Object {
       @objc dynamic var name: String?
       @objc dynamic var itemid = RealmOptional<Int>()
       @objc dynamic var cateid = RealmOptional<Int>()
    }
    

For more information on each solution please see this SO answer and the Realm documentation.