Search code examples
pythondatabasepostgresqlfastapiasyncpg

Force encode/databases to use asyncpg instead of psycopg2


Recently, I am trying to use encode/databases packages with my postgres db. I have done all correctly. But when I go to run it with uvicorn, I see that it shows me that psycopg2 is not installed. I do not wan to use psycopg2. So, I restated all and run databases[postgresql] instead of databases only. I also installed asyncpg. But I am still seeing the same err. I was also doing everything in a virtual environment. My code is attached below:

import databases, sqlalchemy, asyncpg
from fastapi import FastAPI

#POSTGRES DATABASE
DATABASE_URL = "postgresql://xxxxxxxxxxx" # hidden
database = databases.Database(DATABASE_URL)
metadata = sqlalchemy.MetaData()

users = sqlalchemy.Table(
    "py_users",
    metadata,
    sqlalchemy.Column("id"        , sqlalchemy.String, primary_key=True),
    sqlalchemy.Column("username"  , sqlalchemy.String),
    sqlalchemy.Column("password"  , sqlalchemy.String),
    sqlalchemy.Column("first_name", sqlalchemy.String),
    sqlalchemy.Column("last_name" , sqlalchemy.String),
    sqlalchemy.Column("gender"    , sqlalchemy.CHAR  ),
    sqlalchemy.Column("created_at", sqlalchemy.String),
    sqlalchemy.Column("status"    , sqlalchemy.CHAR  ),
)

engine = sqlalchemy.create_engine(
    DATABASE_URL
)
metadata.create_all(engine)

app = FastAPI()

@app.get('/users')
def find_all_users():
    return "List All Users"

and the traceback is:

INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [110] using statreload
Process SpawnProcess-1:
Traceback (most recent call last):
  File "/usr/lib/python3.8/multiprocessing/process.py", line 315, in _bootstrap
    self.run()
  File "/usr/lib/python3.8/multiprocessing/process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
  File "/home/runner/HelloCoderFastAPITuto/env/lib/python3.8/site-packages/uvicorn/subprocess.py", line 61, in subprocess_started
    target(sockets=sockets)
  File "/home/runner/HelloCoderFastAPITuto/env/lib/python3.8/site-packages/uvicorn/_impl/asyncio.py", line 47, in run
    loop.run_until_complete(self.serve(sockets=sockets))
  File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "/home/runner/HelloCoderFastAPITuto/env/lib/python3.8/site-packages/uvicorn/_impl/asyncio.py", line 54, in serve
    config.load()
  File "/home/runner/HelloCoderFastAPITuto/env/lib/python3.8/site-packages/uvicorn/config.py", line 306, in load
    self.loaded_app = import_from_string(self.app)
  File "/home/runner/HelloCoderFastAPITuto/env/lib/python3.8/site-packages/uvicorn/importer.py", line 23, in import_from_string
    raise exc from None
  File "/home/runner/HelloCoderFastAPITuto/env/lib/python3.8/site-packages/uvicorn/importer.py", line 20, in import_from_string
    module = importlib.import_module(module_str)
  File "/usr/lib/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 783, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "./main.py", line 22, in <module>
    engine = sqlalchemy.create_engine(
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/sqlalchemy/engine/__init__.py", line 500, in create_engine
    return strategy.create(*args, **kwargs)
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/sqlalchemy/engine/strategies.py", line 87, in create
    dbapi = dialect_cls.dbapi(**dbapi_args)
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/sqlalchemy/dialects/postgresql/psycopg2.py", line 778, in dbapi
    import psycopg2
ModuleNotFoundError: No module named 'psycopg2'

From the above errors I think that the package databases is trying to use psycopg2 instead of asyncpg. And in that case how do I force the databases package to use asyncpg instead of psycopg2. If that is not the case how do I use asyncpg instead of using psycopg2?

Thanks in advance.

My question may have some mistakes. Please ignore those silly mistakes and just edit the question if you find any mistakes in my question


Solution

  • No, in your case SQLAlchemy trying to use psycopg2.

    See the error:

    opt/virtualenvs/python3/lib/python3.8/site-packages/sqlalchemy/dialects/postgresql/psycopg2.py

    When declaring tables, it is done by SQLAlchemy. But the connections between that, it is done by asyncpg.

    In the documentation it clearly states

    Driver support is providing using one of asyncpg.

    So you do not need to worry about that. Encode will use asyncpg.