4 votes

Insérer plusieurs enregistrements dans une base de données avec Vapor3

Je veux être capable d'ajouter des enregistrements en masse à une base de données nosql dans Vapor 3.

C'est ma structure.

struct Country: Content {

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

}

J'essaie donc de transmettre un tableau d'objets JSON, mais je ne sais pas comment structurer la route ni comment accéder au tableau pour décoder chaque objet.

J'ai essayé cette voie :

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

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

avec cette fonction :

 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
    }
    }
}

Alors comment structurer la route et la fonction pour avoir accès à chaque pays ?

3voto

JoannisO Points 720

Je ne sais pas quelle base de données NoSQL vous envisagez d'utiliser, mais les versions bêta actuelles de MongoKitten 5 et Meow 2.0 rendent la tâche assez facile.

Veuillez noter que nous n'avons pas encore écrit de documentation pour ces deux bibliothèques car nous avons d'abord mis en place une API stable. Le code suivant est à peu près ce dont vous avez besoin avec 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
    }
}

0voto

mcritz Points 545

J'ai eu un besoin similaire et je veux partager ma solution de traitement en vrac dans Vapor 3. J'aimerais qu'un autre développeur expérimenté m'aide à affiner ma solution.

Je vais faire de mon mieux pour expliquer ce que j'ai fait. Et j'ai probablement tort.

D'abord, rien de spécial dans le routeur . Ici, je manipule un POST pour items/batch pour un tableau JSON d'éléments.

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

Ensuite, le contrôleur manipulateur .

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)
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X