1

I want to deploy a FastAPI application with Heroku and Heroku Postgres. Unfortunately, Heroku deployment database URL starts with postgres:// whereas SQLAlchemy now only allows for postgresql://. Thus, I want to update the DATABASE_URL variable directly in the application itself.

I've tried to update it manually and as to several suggestions in Pydantic:

def get_database_url(url):
    if url.startswith("postgres://"):
        url = url.replace("postgres://", "postgresql://", 1)
    return URL

#attempt 1
class Settings(BaseSettings):
    load_dotenv()

    DATABASE_URL: str = get_database_url(os.getenv("DATABASE_URL"))


#attempt 2
class Settings(BaseSettings):
    ...

    class Config:
        @validator("DATABASE_URL", pre=True)
        def parse_env_var(cls, value: str):
            return get_database_url(value)

#attempt 3
class Settings(BaseSettings):
    ...

    class Config:
        @classmethod
        def parse_env_var(cls, field_name: str, raw_val: str) -> Any:
            if field_name == 'DATABASE_URL':
                return get_database_url(raw_val)
            return cls.json_loads(raw_val)


All of which give the same error:

sqlalchemy.exc.NoSuchModuleError: Can't load plugin: sqlalchemy.dialects:postgres

How can I update this value after getting it from the environment file?

Ha Tran
  • 25
  • 5
  • You appear to be calling `os.getenv(url)`, but where is the variable `url` defined? And isn't this always going to be `DATABASE_URL`? It's not clear why you're using a variable here. – larsks Sep 06 '22 at 02:15
  • Sorry about that, just updated my question! – Ha Tran Sep 06 '22 at 18:32

1 Answers1

1

The problem is with SQLAlchemy, not the way you are specifying or getting the URL.

I SQLAlchemy removed support for "postgres://", see here for info: sqlalchemy.exc.NoSuchModuleError: Can't load plugin: sqlalchemy.dialects:postgres

You can try this: postgresql+psycopg2://

Zaffer
  • 1,290
  • 13
  • 32