Vapor 4 中的原始查询

Raw Query In Vapor 4

在 Vapor 3 中,我能够获得到数据库的新连接并使用以下命令调用原始 sql 查询:

return request.withNewConnection(to: .mysql) { (con) -> EventLoopFuture<T> in  
    return con.raw(sql)...
}

现在我正在将我的代码迁移到 Vapor 4,函数 raw 或 withNewConnection 已经消失,我可以使用什么来进行原始查询。

重现步骤

return request.withNewConnection(to: .mysql) { (con) -> EventLoopFuture<T> in  
...
}

错误: 无法推断参考成员的上下文基础 'mysql' 'Request' 类型的值没有成员 'withNewConnection'

预期行为

在 request.db 中有一个函数可以让我获得新连接或 运行 原始查询。

环境

试试这个:

import SQLKit
struct Row:Content
{
    // fields go here
}
struct Context:Decodable
{
    let rows:[Row]
}
func rawDemo(_ request:Request) throws -> EventLoopFuture<View>
{
    return (request.db as! SQLDatabase).raw("SELECT * FROM MyTable").all(decoding:Row.self).flatMap
    {
        results in
        let context = Context(rows:results)
        return request.view.render("rawDemo", context)
    }
}

您必须如图所示导入 SQLKit 模块并将 request.db 转换为 SQLDatabase 才能执行原始查询。一旦你这样做了,它就会变得很像 Vapor 3 方法。然而,有了 Vapor 4 中可用的新功能,我现在已经设法摆脱了所有原始查询,并用流畅的 Fluent 查询取而代之!

Error: Cannot infer contextual base in reference to member 'mysql' Value of type 'Request' has no member 'withNewConnection'

不幸的是,

Fluent 4 数据库标识符 .mysql 不再通用。所以你必须一直像这样 request.db as! SQLDatabase 来转换它,以获得像 raw(...) 这样的方法来执行你的原始查询。现在连接也深入内部。

我建议用 Vapor 4

看看 SwifQL + Bridges
import Vapor
import MySQLBridge

struct MyResult: Codable {
    let column1: String
    let column2: Int
}
func someHandler(_ req: Request) throws -> EventLoopFuture<[MyResult]> {
    req.mysql.connection(to: .myDatabase) { conn in
        SwifQL
            .select(\SomeTable.$column1, \SomeTable.$column2)
            .from(SomeTable.table)
            .execute(on: conn)
            .all(decoding: MyResult.self)
    }
}

SwifQL 是一种 DSL,使您能够安全地构建任何原始查询,而 Bridges 是 mysql-niopostgres-nio 等数据库驱动程序的助手,因此它只为它们提供了方便的方法。