0

我有一个同时采用TableRecord和的课程FetchableRecord。我标记了 GRDB 提供的自动查询生成的优势,我只提供表名,因为它与类名不匹配。但是现在我想添加仅在运行时使用的存储属性,并且我不希望 GRDB 尝试自动获取这些属性。我可以从查询中排除某些变量吗?

这是我的代码:

class Question: Identifiable, Codable, TableRecord, FetchableRecord {
    static var databaseTableName = "questions"
    
    var id: Int?
    var category: Int?
    var code: String?
    var ...
    var ...
    var ...
    var ...
    var selectedAnswer: Int? // This is only used at run-time and not present in the database.
}

我找到了这个:

static var databaseSelection = [Column("id"), Column("category"), Column("code"), ...]

但这需要我手动指定我希望它获取的所有列。我可以做相反的事情,只排除一列(selectedAnswer)吗?

基本上我正在寻找的是这样的:

static var excludedVariables = ["selectedAnswer"]

我通读了文档但找不到任何东西,但我不知道 GRDB,所以我可能错过了一些东西。

4

2 回答 2

1

我认为这不是一个特定的 GRDB 问题,而更多的是一个Codable问题,即“如何排除一个属性被解码”。因此,您的解决方案可能是明确定义编码键,而不是让 Swift 合成它们:

enum CodingKeys: String, CodingKey {
  case id, category, code, ...
}

它仍然需要您定义所有列/属性,但是Codable当您想要排除某些属性时,情况总是如此。

于 2022-01-31T17:25:34.733 回答
0

你不需要做任何事情:

  • 默认情况下,GRDB 选择所有列 ( SELECT * FROM ...)。如果非持久属性没有列,则不会获取它(并且不会在生成的 SQL 中插入无效列)。
  • 可选属性被解码为nil解码行中不存在的列。

例如:

import GRDB

var configuration = Configuration()
configuration.prepareDatabase { db in
    db.trace { print("SQL> \($0)") }
}
let dbQueue = DatabaseQueue(configuration: configuration)

struct Player: Identifiable, Codable, TableRecord, FetchableRecord {
    var id: Int64
    var name: String
    var score: Int
    var ignored: Int? // Has no matching column in the database
}

try dbQueue.write { db in
    try db.create(table: "player") { t in
        t.autoIncrementedPrimaryKey("id")
        t.column("name", .text).notNull()
        t.column("score", .integer).notNull()
    }

    try db.execute(sql: """
        INSERT INTO player (id, name, score) VALUES (NULL, 'Arthur', 100);
        INSERT INTO player (id, name, score) VALUES (NULL, 'Barbara', 1000);
        """)
    
    // SELECT * FROM player
    let players = try Player.fetchAll(db)

    // [Player(id: 1, name: "Arthur", score: 100, ignored: nil),
    //  Player(id: 2, name: "Barbara", score: 1000, ignored: nil)]
    print(players)
}
于 2022-02-01T13:00:21.190 回答