【问题标题】:Insert multiple records into database with Vapor3使用 Vapor3 将多条记录插入数据库
【发布时间】:2019-02-21 11:15:46
【问题描述】:

我希望能够在 Vapor 3 中向 nosql 数据库批量添加记录。

这是我的结构。

struct Country: Content {

   let countryName: String
   let timezone: String
   let defaultPickupLocation: String

}

所以我试图传递一个 JSON 对象数组,但我不确定如何构造路由,也不确定如何访问数组来解码每个对象。

我试过这条路线:

    let countryGroup = router.grouped("api/country")

    countryGroup.post([Country.self], at:"bulk", use: bulkAddCountries)

使用此功能:

 func bulkAddCountries(req: Request, countries:[Country]) throws ->  Future<String> {
    for country in countries{
    return try req.content.decode(Country.self).map(to: String.self) { countries in



        //creates a JSON encoder to encode the JSON data
        let encoder = JSONEncoder()
        let countryData:Data
        do{
            countryData = try encoder.encode(country) // encode the data
        } catch {
            return "Error. Data in the wrong format."
        }
        // code to save data
    }
    }
}

那么我如何构建路径和函数以访问每个国家/地区?

【问题讨论】:

    标签: arrays json record vapor


    【解决方案1】:

    我不确定您打算使用哪个 NoSQL 数据库,但目前的 MongoKitten 5 和 Meow 2.0 测试版让这很容易。

    请注意,当我们首先推送到稳定的 API 时,我们还没有为这两个库编写文档。以下代码大致是您使用 MongoKitten 5 所需要的:

    // Register MongoKitten to Vapor's Services
    services.register(Future<MongoKitten.Database>.self) { container in
        return try MongoKitten.Database.connect(settings: ConnectionSettings("mongodb://localhost/my-db"), on: container.eventLoop)
    }
    
    // Globally, add this so that the above code can register MongoKitten to Vapor's Services
    extension Future: Service where T == MongoKitten.Database {}
    
    // An adaptation of your function
    func bulkAddCountries(req: Request, countries:[Country]) throws ->  Future<Response> {
        // Get a handle to MongoDB
        let database = req.make(Future<MongoKitten.Database>.self)
    
        // Make a `Document` for each Country
        let documents = try countries.map { country in
            return try BSONEncoder().encode(country)
        }
    
        // Insert the countries to the "countries" MongoDB collection
        return database["countries"].insert(documents: documents).map { success in
            return // Return a successful response
        }
    }
    

    【讨论】:

    • 谢谢。这看起来很有用。由于我在内部托管的位置,我不得不使用 FoundationDB 而不是 MongoDB,因此没有 Vapor Fluent 连接器,因此必须自己解决问题。
    【解决方案2】:

    我也有类似的需求,想分享我的Vapor 批量处理解决方案 3。我很想请其他经验丰富的开发人员帮助完善我的解决方案。

    我会尽力解释我做了什么。我可能错了。

    首先,路由器没有什么特别之处。在这里,我正在处理一个 POST 到 items/batch 的 JSON 数组项。

    router.post("items", "batch", use: itemsController.handleBatch)
    

    然后是控制器的处理程序

    func createBatch(_ req: Request) throws -> Future<HTTPStatus> {
        // Decode request to [Item]
        return try req.content.decode([Item].self)
            // flatMap will collapse Future<Future<HTTPStatus>> to [Future<HTTPStatus>]
            .flatMap(to: HTTPStatus.self) { items in
            // Handle each item as 'itm'. Transforming itm to Future<HTTPStatus>
            return items.map { itm -> Future<HTTPStatus> in
                // Process itm. Here, I save, producing a Future<Item> called savedItem
                let savedItem = itm.save(on: req)
                // transform the Future<Item> to Future<HTTPStatus>
                return savedItem.transform(to: HTTPStatus.ok)
            }
            // flatten() : “Flattens an array of futures into a future with an array of results”
            // e.g. [Future<HTTPStatus>] -> Future<[HTTPStatus]>
            .flatten(on: req)
            // transform() : Maps the current future to contain the new type. Errors are carried over, successful (expected) results are transformed into the given instance.
            // e.g. Future<[.ok]> -> Future<.ok>
            .transform(to: HTTPStatus.ok)
        }
    }
    

    【讨论】:

    • 我希望得到来自@tanner0101 的反馈
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 2018-05-07
    • 1970-01-01
    • 2016-08-17
    • 2021-04-07
    • 1970-01-01
    相关资源
    最近更新 更多