【问题标题】:Decoding Vapor raw query to MySQLModel将 Vapor 原始查询解码为 MySQLModel
【发布时间】:2020-04-21 08:34:52
【问题描述】:

我正在尝试在 Vapor 应用程序中运行 SQL 原始查询,并解码为 MySQLModel,但显然它返回了错误。

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

但是当我运行一个简单的从原始查询中选择时,它返回一个解码错误:“键'title'需要'String'类型的值。”这很奇怪,因为在 MySQL 控制台中运行的 sql 确实运行正确。问题是当我解码相同的查询时,我使用的是这样的内容,而不是使用 MySQLModel:

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

这实际上是在没有错误的情况下结束解码。

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

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

SELECT * FROM ClassA

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

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

注意:在 MySQL 控制台中运行时,查询不会返回错误,并且如上所述,查询可以解码为与 ClassA 完全相同的 Content 类示例:ClassB。

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

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

【问题讨论】:

  • 该表确实存在,但它是在 MySQLWorkbench 中创建的,而不是迁移。我不认为这也是问题所在,因为 ClassB 确实可以工作,如果它不存在那将无法工作,它必须与 MySQLModel 类一起使用。 @尼克
  • 而我可以完美地使用ORM的类是当我使用Raw Query时的问题。
  • 您能否发布原始查询以及您如何尝试对其进行解码?
  • 我编辑了@Nick sql 实际上是问题的一部分。
  • @Nick 显然问题在于将表命名为“c”。

标签: swift vapor


【解决方案1】:

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

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

SELECT * FROM ClassA;

这个查询:

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

除了子查询之外,将表命名为“c”,由于某种原因,这种表示法对于在 Vapor 中解码 MySQLModel 类型无效,它们仅适用于内容类型。

解决办法是去掉符号,在查询中使用全名:

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

【讨论】:

    猜你喜欢
    • 2020-09-20
    • 2018-09-12
    • 2015-06-26
    • 1970-01-01
    • 2019-02-03
    • 2012-09-18
    • 2019-04-29
    • 2015-01-31
    • 2016-10-20
    相关资源
    最近更新 更多