问题
I am experimenting with a standalone script that will query a Postgres database using Vapor and Fluent. In a normal Vapor API application this is simply done by:
router.get("products") { request in
return Product.query(on: request).all()
}
However, in a standalone script, since there is no "request", I get stuck on what to replace the "request" or DatabaseConnectable
with. Here's where I get stuck on:
import Fluent
import FluentPostgreSQL
let databaseConfig = PostgreSQLDatabaseConfig(hostname: "localhost",
username: "test",
database: "test",
password: nil)
let database = PostgreSQLDatabase(config: databaseConfig)
let foo = Product.query(on: <??WhatDoIPutHere??>)
I tried creating an object that conforms to DatabaseConnectable
, but couldn't figure out how to correctly get that object to conform.
回答1:
You will need to create an event loop group to be able to make database requests. SwiftNIO's MultiThreadedEventLoopGroup
is good for this:
let worker = MultiThreadedEventLoopGroup(numberOfThreads: 2)
You can change the number of threads used as you need.
Now you can create a connection to the database with that worker:
let conn = try database.newConnection(on: worker)
The connection is in a future, so you can map
it and pass the connection in your query:
conn.flatMap { connection in
return Product.query(on: connection)...
}
Make sure you shutdown your worker when you are done with it using shutdownGracefully(queue:_:)
回答2:
The above is very good, but just clarify how simple it is, when you get it, I have made a small test example for this. Hope it helps you.
final class StandAloneTest : XCTestCase{
var expectation : XCTestExpectation?
func testDbConnection() -> Void {
expectation = XCTestExpectation(description: "Wating")
let databaseConfig = PostgreSQLDatabaseConfig(hostname: "your.hostname.here",
username: "username",
database: "databasename",
password: "topsecretpassword")
let database = PostgreSQLDatabase(config: databaseConfig)
let worker = MultiThreadedEventLoopGroup(numberOfThreads: 2)
let conn = database.newConnection(on: worker)
let sc = SomeClass( a:1, b:2, c:3 ) //etc
//get all the tupples for this Class type in the base
let futureTest = conn.flatMap { connection in
return SomeClass.query(on: connection).all()
}
//or save a new tupple by uncommenting the below
//let futureTest = conn.flatMap { connection in
// return someClassInstantiated.save(on: connection)
//}
//lets just wait for the future to test it
//(PS: this blocks the thread and should not be used in production)
do{
let test = try futureTest.wait()
expectation?.fulfill()
worker.syncShutdownGracefully()
print( test )
}catch{
expectation?.fulfill()
print(error)
}
}
}
//Declare the class you want to test here using the Fluent stuff in some extension
来源:https://stackoverflow.com/questions/53786970/is-is-possible-to-use-vapor-3-postgres-fluent-in-a-standalone-script