将 Vapor 原始查询解码为 MySQLModel

Decoding Vapor raw query to MySQLModel

我正在尝试 运行 在 Vapor 应用程序中进行 SQL 原始查询,并解码为 MySQL 模型,但显然它 return 是一个错误。

final class ClassA: MySQLModel {    
    var id: Int?
    var title: String
    var description: String
}

但是当我 运行 一个简单的 Select 来自原始查询时它 return 是一个解码错误:"Value of type 'String' required for key 'title'." 这很奇怪,因为 sql [= MySQL 控制台中的 47=] 正确地 运行。问题是当我解码相同的查询但没有使用 MySQL 模型时,我使用了这样的内容:

final class ClassB: Content {    
    var id: Int?
    var title: String
    var description: String
}

而这实际上是无误解码结束。

编辑: ClassA 与常规 ORM 完美配合,只有当我尝试从原始查询解码时才会失败。

编辑: 正如@Nick 所问,sql 确实会影响响应,当 运行:

SELECT * FROM ClassA

return 没有错误返回,但我的 sql 包含一个复杂的子查询,如下所示:

SELECT c.* FROM ClassA c WHERE c.id IN (SELECT id FROM ...);

注意:当 运行 在 MySQL 控制台中时,查询 return 没有错误,并且如前所述,查询可以解码为内容 class 与 ClassA 示例完全相同: ClassB.

编辑: 运行宁和解码原始查询的代码很简单:

return request.withNewConnection(to: .mysql) { (con) -> EventLoopFuture<[ClassA]> in
    return con.raw(sql).all(decoding: ClassA.self).map { (classes) -> [ClassA] in
        return classes
    }
}

我通过尝试对同一查询进行不同排列来解决问题,正如@Nick 提出的那样。

问题出在查询上(不是最初想的子查询),这个查询的区别:

SELECT * FROM ClassA;

这个查询:

SELECT c.* FROM ClassA c WHERE c.id IN (SELECT id FROM ...);

除了子查询是 table 到 "c" 的命名之外,由于某种原因,这种表示法对于解码 Vapor 中的 MySQLModel 类型是无效的,它们只适用于内容类型。

解决方案是删除符号并在查询中使用整个名称:

SELECT ClassA.* FROM ClassA WHERE ClassA.id IN (SELECT id FROM ...);