Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Difference fields in database and data model #438

Closed
Mahdimm opened this issue Nov 4, 2018 · 5 comments
Closed

Difference fields in database and data model #438

Mahdimm opened this issue Nov 4, 2018 · 5 comments
Labels

Comments

@Mahdimm
Copy link

Mahdimm commented Nov 4, 2018

Hi @tonyarnold

I have a table with 3 columns but its model has 4 properties, What should I do in this case? because when I set insert query I got this error:

Fatal error: 'try!' expression unexpectedly raised an error: SQLite error 1 with statement INSERT INTO "student" ("id", "name", "lastName", "age") VALUES (?,?,?,?): table student has no column named age!

My table columns are: id, name, lastName
My model properties: id, name, lastName, age

is there any protocol that I can fix this problem?

@groue
Copy link
Owner

groue commented Nov 4, 2018

Hi @Mahdimm,

is there any protocol that I can fix this problem?

You did not say much, so I'll suppose that you use the PersistableRecord protocol, the one which provides the GRDB persistence methods such as insert, update, etc.

You control the stored columns with the encode(to:) method. In your case, store id, name, lastName, but omit age:

func encode(to container: inout PersistenceContainer) {
    container["id"] = id
    container["name"] = name
    container["lastName"] = lastName
}

If you happen to use the standard Encodable protocol on top of PersistableRecord, then refer to the "Choose Properties to Encode and Decode Using Coding Keys" paragraph of the Encoding and Decoding Custom Types documentation.

@Mahdimm
Copy link
Author

Mahdimm commented Nov 5, 2018

thanks for replay @groue

We solved problem in this way and maybe this code help someone who is searching for same problem:

struct Student: Codable, TableRecord {
    var id : Int64?
    var name: String
    var lastName: String? //this is an optional property and maybe set Null in Database
    var age: Int? // we have this field in our model but do not have in our databse!

    init(id:Int64?, name:String, lastName: String, age: Int?) {
        self.id = id
        self.name = name
        self.lastName = lastName
        self.age = age
    }

    //read data from database
    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        id = try values.decode(Int64.self, forKey: .id)
        name = try values.decode(String.self, forKey: .name)
        lastName = try! values.decode(String?.self, forKey: .lastName)
        age = 0 // set our default value here
    }

    //insert data to database
    func encode(to container: inout PersistenceContainer) {
        container["id"] = id
        container["name"] = name
        container["lastName"] = lastName
    }

}

extension Student: FetchableRecord {  }

extension Student: MutablePersistableRecord {
    static let databaseTableName = "Student"
    
    enum Columns: String, ColumnExpression {
        case id, name, lastName
    }
    
    mutating func didInsert(with rowID: Int64, for column: String?) {
        id = rowID
    }
}

@groue
Copy link
Owner

groue commented Nov 5, 2018

Glad you found your solution, @Mahdimm! Happy GRDB!

@groue groue closed this as completed Nov 5, 2018
@MrShafiee
Copy link

Hello @groue,
I have a question, this line is correct ?
lastName = try! values.decode(String?.self, forKey: .lastName)

in init(from decoder: Decoder) throws function, lastName is optional, to set value for this; @Mahdimm use above line, is that okey? or are there any better ways?

because if we use like this:
try? values.decode(String.self, forKey: .lastName)
app crash with this error: Fatal error: could not convert database value NULL to String , although
its property define optional in its model.

Thanks for your response.

@groue
Copy link
Owner

groue commented Nov 5, 2018

Hello @MrShafiee. Your question is not about GRDB, but about the standard Decodable protocol. Please refer to Apple documentation, or ask your question on Stack Overflow. Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants