如何在 Vapor/Fluent 中正确查询 Postgres JSONB 字段

Posted

技术标签:

【中文标题】如何在 Vapor/Fluent 中正确查询 Postgres JSONB 字段【英文标题】:How to properly query Postgres JSONB field in Vapor/Fluent 【发布时间】:2022-01-08 07:16:57 【问题描述】:

我有一个表,其中包含一些由迁移创建的 jsonb 列,如下所示:

    public func prepare(on database: Database) -> EventLoopFuture<Void> 
        return database.schema(MyTable.schema)
            .id()
            .field(.metadata, .custom("JSONB"), .required)
            .create()
    

我正在尝试过滤 jsonb 字段上的查询。以下是一个有效的简单字符串插值。

//jsonFilters is a dictionary of key value pair for which we want to filter in jsonb field            
            
            var query = MyTable.query(on: db)
            var filterString  = ""
            var cycleCount = 0;
            jsonFilters.forEach(
                (key, value) in
                filterString +=
                "metadata->>'\(key)' = '\(value)' "
                cycleCount+=1
                if(cycleCount < filter.metadata!.count) 
                    filterString += " AND "
                
            )
            query = query.filter(.custom(metadataString))
            // Also filter on something else.
            query = query.filter(....)

但是,这并不安全,并且存在 sql 注入漏洞。有没有办法绑定过滤器参数,例如使用 SQLQueryString?它应该与常规过滤器的其余部分一起使用。 (代码最后一行)​​

【问题讨论】:

【参考方案1】:

以防万一有人在这里遇到同样的情况,使用 SQLQueryString 可以传递参数而不是字符串插值:

        var queryString = SQLQueryString("")
        var cycleCount = 0;
        filter.metadata!.forEach(
            (key, value) in
            
            queryString.appendLiteral("metadata->>")
            queryString.appendInterpolation(bind: key)
            queryString.appendLiteral(" = ")
            queryString.appendInterpolation(bind: value)
           
            cycleCount+=1
            if(cycleCount < filter.metadata!.count) 
                queryString.appendLiteral(" AND ")
            
        )

【讨论】:

以上是关于如何在 Vapor/Fluent 中正确查询 Postgres JSONB 字段的主要内容,如果未能解决你的问题,请参考以下文章

Vapor 2,Fluent 模型子类

Vapor fluent 不会在违反外键约束时抛出

如何为蒸汽添加新的依赖项?

cakephp、i18n .po 文件,如何正确使用它们

采购的PO在哪里查询,SAP里的T-CODE是多少 ,然后我想知道如何通过SAP报表检查出采购入库的价格错误,

更新语句中@po 附近的语法不正确