首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何为asyncpg创建Python 3.x (singleton)类?

如何为asyncpg创建Python 3.x (singleton)类?
EN

Stack Overflow用户
提问于 2020-05-31 02:35:13
回答 1查看 905关注 0票数 1

我想在用下面的方法初始化这个类时组织一个连接池

代码语言:javascript
复制
import asyncio
import asyncpg


class DBCommands:

    def __init__(self, uri: str) -> None:
        loop = asyncio.get_event_loop()
    self.pool: asyncpg.pool.Pool = loop.run_until_complete(asyncpg.create_pool(dsn=uri))

    async def get_id_admins(self) -> list:
        async with self.pool.acquire():
            result = await self.pool.fetch("SELECT chat_id FROM users WHERE role_user = 'admin'")
        admins_id = [row[0] for row in result]
        return admins_id

由于池应该是一个池,因此使用上面的实现,这将不起作用。我决定使用单例,但我不知道如何实现它。下面是我想出来的版本。告诉我如何最好地解决这个问题。此外,我不知道如何最好地关闭连接以及在哪里关闭连接。我是一个使用模式的新手,并且刚刚开始学习OOP。

代码语言:javascript
复制
import asyncio
import asyncpg

class Singleton(type):
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]


class DBManager(metaclass=Singleton):

    @classmethod
    def connect(cls, uri):
        loop = asyncio.get_event_loop()
        return loop.run_until_complete(asyncpg.create_pool(dsn=uri))


class DBCommands:

    def __init__(self, uri) -> None:
        self.uri = uri
        self.pool = DBManager.connect(uri)

    async def get_id_admins(self) -> list:
        async with self.pool.acquire():
            result = await self.pool.fetch("SELECT chat_id FROM users WHERE role_user = 'admin'")
        admins_id = [row[0] for row in result]
        return admins_id

我假设可以将打开和关闭池添加到__aenter____aexit__

EN

回答 1

Stack Overflow用户

发布于 2020-06-02 18:08:43

您可以在异步函数中使用class attribute并在第一次需要时创建池:

代码语言:javascript
复制
class Database:

    self.pool = None

    ...

    async def get_id_admins(self)
        if self.pool is None:
            self.pool = await asyncpg.create_pool(dsn=...`).

我通常使用一个常规类并创建一个附加到全局对象的实例(就像web应用程序的aiohttp应用程序一样),如下所示:

代码语言:javascript
复制
class Database:

    def __init__(self, dsn):
        self.dsn = dsn
        self.pool = None

    async def connect(self):
        """Initialize asyncpg Pool"""
        self.pool = await asyncpg.create_pool(dsn=self.dsn, min_size=2, max_size=4)
        logging.info("successfully initialized database pool")

    async def get_id_admins(self):

    ...

并像这样使用它:

代码语言:javascript
复制
async def startup(app):
    await app.database.connect()

async def shutdown(app):
    await app.database.pool.close()

def main():
    app = web.Application()
    app.database = Database(app.config.DSN)
    app.on_startup.append(startup)
    app.on_shutdown.append(shutdown)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62107042

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档