【问题标题】:How to pass environmental variable (database URL) in Tornado?如何在 Tornado 中传递环境变量(数据库 URL)?
【发布时间】:2019-07-11 00:48:08
【问题描述】:

我有弹性 URL 作为环境变量传递给 post 方法,我已经从 tornado_sqlalchemy 声明了 make_session_factory,并传递给 requesthandler,我应该如何自己接收它,下面是我的代码

class MyHandler(RequestHandler):
    _thread_pool = ThreadPoolExecutor(max_workers=10)

    def initialize(self, session_factory): 
      self.session_factory = session_factory

    @gen.coroutine
    def post(self):
        try:
            data = tornado.escape.json_decode(self.request.body)
            yield self.predict('mod1')
        except Exception:
            self.respond('server_error', 500)

    @concurrent.run_on_executor(executor='_thread_pool')
    def _b_run(self, mod, X):
        results = do some calculation
        return results

    @gen.coroutine
    def predict(self, mod):  
        model = mod(load from database)
        values = (load from database)
        results = yield self._b_run(model, values)
        self.respond(results)

    def respond(self, code=200):
        self.set_status(code)
        self.write(json.JSONEncoder().encode({
            "status": code
        }))
        self.finish()


def mod(model):
    #Elastic Client
    es = Elasticsearch([{'host': 'localhost', 'port': 9200}])
    ……...Load model
    return model


factory = make_session_factory(os.environ.get('DATABASE_URL', ''))
define('port', default=8888, help='Tornado port to listen on')

def make_app():  
    url = [(r"/pred", PredictionHandler)]
    return Application(url,session_factory=factory)

if __name__ == "__main__":
    application = make_app()
    http_server = HTTPServer(application)
    http_server.listen(options.port)
    IOLoop.current().start()

现在我在我的 mod 函数中将 URL 编码为 localhost, 9200,

为了将它作为环境变量传递,我创建了工厂并在我的应用程序中将工厂作为 session_factory 传递,

我必须在我的 requesthandler post 方法中接收它,以便我可以传递给我的 predict 方法,该方法在 tern 调用我的 mod 函数,我可以知道如何接收它。我尝试了初始化但无法正常工作。

还找到了使用带龙卷风的电机的另一个选项

import motor.motor_tornado
client = motor.motor_tornado.MotorClient('localhost', 9200)
db = motor.motor_tornado.MotorClient().test_database

application = tornado.web.Application([
    (r'/', MainHandler)
], db=db)

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        db = self.settings['db']

这里我也必须在我的 post 方法中接收

【问题讨论】:

    标签: tornado tornado-motor


    【解决方案1】:

    您传递给Application 类的任何额外参数都将在您的任何请求处理程序的self.settings 中可用。

    所以你可以像这样修改initialize方法:

    def initialize(self): 
        self.session_factory = self.settings['session_factory']
    
    # and just use `self.session_factory` in any other method where you need it
    

    【讨论】:

    • 非常感谢,我这样做了,我收到了类似 sqlalchemy.exc.ArgumentError: Could not parse rfc1738 URL from string '' 的错误,这是正确的语法 factory = make_session_factory(os.environ. get('DATABASE_URL', ''))
    • 目前我通过 'localhost:9200' 代替 'DATABASE_URL' 进行检查,这应该可以正常工作,对吗
    • @hanzgs 试试这个:os.environ.get('DATABASE_URL', 'localhost:9200')。如果 DATABASE_URL 环境变量不存在,python 将使用 localhost:9200 作为默认值。
    • 谢谢,也试过了,仍然收到 ArgumentError 错误:无法从字符串 'localhost:9200' 解析 rfc1738 URL
    • @hanzgs 根据sqlalchemy docs,网址应如下所示:dialect+driver://username:password@host:port/database。请在the linked page 上查看更多示例,并使用特定于您的数据库的适当网址。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-06
    • 2021-08-27
    • 1970-01-01
    • 2022-06-19
    • 2020-03-27
    • 2019-09-24
    相关资源
    最近更新 更多