有时在模块中从`getenv`清空连接字符串

时间:2018-03-05 18:55:47

标签: python postgresql tornado connection-pooling

我们有一个db_connection.py模块,如下所示。

from os import getenv
from collections import OrderedDict
import asyncpg
from tornado import gen
from util.utils import custom_exception
import time

db_name = getenv("DB_NAME", "XXX")
db_user = getenv("DB_USER", "YYY")
db_password = getenv("DB_PASSWORD", "ZZZ")
db_host = getenv("DB_HOST", "localhost")
db_port = getenv("DB_PORT", "5432")

db_args = dict(user=db_user, password=db_password,
               database=db_name, host=db_host, port=db_port)

class db_connection(object):
    def __init__(self, **db_args):
        self.db_pool = []
        self.init(**db_args)

    # create a pool ref coroutine where we can get connections from
    # needs user, password, database, host, port
    @gen.coroutine
    def init(self,**db_args):
        self.db_pool = yield asyncpg.create_pool(**db_args)

    @gen.coroutine
    def exit(self):
        yield self.db_pool.close()

    # run a queer
    async def run(self,q):
        if not self.db_pool:
            self.init() #try again
            if not self.db_pool:
                raise custom_exception(reason='Database connection error', status_code=500)
        async with self.db_pool.acquire() as connection:
            ret = await connection.fetch(q)
            # format to match the old data types
            return [OrderedDict(e) for e in ret]

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.exit()
        self.db_pool = []

在app中,我们按如下方式初始化db_connection对象:

from util.db_connection import db_args, db_connection
(...)
if __name__ == "__main__":
    AsyncIOMainLoop().install()

    dbc = db_connection(**db_args)

    # What we have here is a rather basic tornado app 
    app = make_app()
    app.listen(port=8080)
    asyncio.get_event_loop().run_forever()

我们看到的问题是,这是我无法解释的,似乎连接字符串(db_args)并不总是设置,有时似乎是一个空字典; asyncpg然后回退并尝试通过os从与容器关联的linux用户获取连接字符串。

Mar  5 16:59:50 ABC: ERROR:
tornado.application:Future <tornado.concurrent.Future object at 0x7eff6005c320>  
  exception was never retrieved: 

Traceback (most recent call last): 
  File "/usr/local/lib/python3.6/site-packages/tornado/gen.py", line 1063, in run  
    yielded = self.gen.throw(*exc_info) 
  File "/abc/def/db_connection.py", line 26, in init   
    self.db_pool = yield asyncpg.create_pool(**db_args)  
  File "/usr/local/lib/python3.6/site-packages/tornado/gen.py", line 1055, in run 
    value = future.result() 
  File "/usr/local/lib/python3.6/site-packages/tornado/concurrent.py", line 238, in result    
    raise_exc_info(self._exc_info) Mar  5 16:59:50 ABC:  File "<string>", line 4, in raise_exc_info  
  File "/usr/local/lib/python3.6/site-packages/tornado/gen.py", line 307, in wrapper 
    yielded = next(result) 
  File "<string>", line 6, in _wrap_awaitable 
  File "/usr/local/lib/python3.6/site-packages/asyncpg/pool.py", line 356, in _async__init__ 
    await first_ch.connect() 
  File "/usr/local/lib/python3.6/site-packages/asyncpg/pool.py", line 126, in connect 
    **self._connect_kwargs) 
  File "/usr/local/lib/python3.6/site-packages/asyncpg/connection.py", line 1498, in connect   
    max_cacheable_statement_size=max_cacheable_statement_size) 
  File "/usr/local/lib/python3.6/site-packages/asyncpg/connect_utils.py", line 296, in _connect 
    addrs, params, config=_parse_connect_arguments(timeout=timeout, **kwargs) 
  File "/usr/local/lib/python3.6/site-packages/asyncpg/connect_utils.py", line 242, in _parse_connect_arguments 
    server_settings=server_settings) 
  File "/usr/local/lib/python3.6/site-packages/asyncpg/connect_utils.py", line 152, in _parse_connect_dsn_and_args 
    user=getpass.getuser() 
  File "/usr/local/lib/python3.6/getpass.py", line 169, in getuser 
    return pwd.getpwuid(os.getuid())[0] 
    KeyError: 'getpwuid(): uid not found: 10001

0 个答案:

没有答案