Sitelet https://web.archive.org/web/20201011071217/https://github.com/MagicStack/asyncpg/issues/602
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Please add scalable app file structure in documentation. Also is my approach correct? #602

Open
gauravsaini964 opened this issue Jul 26, 2020 · 0 comments

Comments

@gauravsaini964
Copy link

@gauravsaini964 gauravsaini964 commented Jul 26, 2020 •

  • asyncpg version:
  • PostgreSQL version:
  • Do you use a PostgreSQL SaaS? If so, which? Can you reproduce
    the issue with a local PostgreSQL install?
    :
  • Python version:
  • Platform:
  • Do you use pgbouncer?:
  • Did you install asyncpg with pip?:
  • If you built asyncpg locally, which version of Cython did you use?:
  • Can the issue be reproduced under both asyncio and
    uvloop?
    :

Latest version of asyncpg
No PGBouncer
Python 3.8.2

Hi, I am using fast API but I have no idea how to maintain DB connection and pool. I am switching from Django ORM but still, it is hard for me to get a good grasp on this. Please guide me on how can I improve this and also add this to your documentation.

My questions:
How to maintain a constant database connection?
How to maintain a pool of connections?
How to use the same connection out of the pool for every query in the same request?

Is my naive solution correct? How can I improve this and make this production-ready?

db_connection.py

`import asyncpg
from configs.settings import settings


class Database:
    def __init__(self):
        self.user = settings.POSTGRES_USER
        self.password = settings.POSTGRES_PASSWORD
        self.host = settings.POSTGRES_SERVER
        self.port = "5432"
        self.database = settings.POSTGRES_DB
        self._cursor = None

        self._connection_pool = None
        self.con = None

    async def connect(self):
        if not self._connection_pool:
            try:
                self._connection_pool = await asyncpg.create_pool(
                    min_size=1,
                    max_size=10,
                    command_timeout=60,
                    host=self.host,
                    port=self.port,
                    user=self.user,
                    password=self.password,
                    database=self.database,
                )

            except Exception as e:
                print(e)

    async def fetch_rows(self, query: str):
        print(query)
        if not self._connection_pool:
            print("shouldnt be here")
            await self.connect()
        else:
            self.con = await self._connection_pool.acquire()
            try:
                result = await self.con.fetch(query)
                print(result)
                return result
            except Exception as e:
                print(e)
            finally:
                print("pool released")
                await self._connection_pool.release(self.con)

`

db_session.py

`from .db_connection import Database

database_instance = Database()

`

main.py

`from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware


from routes import items, user

from utils.middleware import middleware
from configs import open_api_tags
from configs.settings import settings
from db.db_session import database_instance

app = FastAPI(
    title=settings.PROJECT_NAME,
    description=settings.PROJECT_DESCRIPTION,
    version="0.0.1",
    openapi_tags=open_api_tags.tags_metadata,
)


app.add_middleware(
    CORSMiddleware,
    allow_origins=settings.BACKEND_CORS_ORIGINS,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


app.middleware("http")(middleware)


@app.on_event("startup")
async def startup():
    await database_instance.connect()


app.include_router(user.router)
app.include_router(items.router, prefix="/items")
`

user.py

`from fastapi import APIRouter
from db.db_session import database_instance

router = APIRouter()

@router.get("/users/me", tags=["users"])
async def read_user_me():
    result = await database_instance.fetch_rows("SELECT * from user")
    print(result)
    return {"username": "fakecurrentuser"}`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
1 participant
You can’t perform that action at this time.