I have a table called city in PostgreSQL
CREATE TABLE CITY (
CITYID serial PRIMARY KEY,
CNAME VARCHAR (50) UNIQUE NOT NULL,
STATE VARCHAR (50) NOT NULL
);
When I use simple select with SQLAlchemy it works fine
query = session.query(models.City)
cities = query.all() #works fine
cities = session.execute("SELECT cityid, cname FROM city where cityid = 1").fetchall() # works fine
By doing above, I make sure that my session works fine and connecting the DB properly.
When I try to call a stored procedure in SQLAlchemy it is not working.
Here is my SP (Postgres)
create or replace procedure addcity(
cname varchar(20),
state varchar(20)
)
language plpgsql
as $$
begin
insert into city
(cname, state)
values (cname, state);
commit;
end;$$
Here is my SQLAlchemy code:
session.execute('CALL addcity (?, ?)', [('One', 'Two')])
The above code throws error as below:
Traceback (most recent call last):
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/uvicorn/protocols/http/h11_impl.py", line 369, in run_asgi
result = await app(self.scope, self.receive, self.send)
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/uvicorn/middleware/proxy_headers.py", line 59, in __call__
return await self.app(scope, receive, send)
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/fastapi/applications.py", line 208, in __call__
await super().__call__(scope, receive, send)
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/starlette/applications.py", line 112, in __call__
await self.middleware_stack(scope, receive, send)
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/starlette/middleware/errors.py", line 181, in __call__
raise exc from None
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/starlette/middleware/errors.py", line 159, in __call__
await self.app(scope, receive, _send)
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/starlette/exceptions.py", line 82, in __call__
raise exc from None
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/starlette/exceptions.py", line 71, in __call__
await self.app(scope, receive, sender)
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/starlette/routing.py", line 580, in __call__
await route.handle(scope, receive, send)
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/starlette/routing.py", line 241, in handle
await self.app(scope, receive, send)
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/starlette/routing.py", line 52, in app
response = await func(request)
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/fastapi/routing.py", line 219, in app
raw_response = await run_endpoint_function(
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/fastapi/routing.py", line 154, in run_endpoint_function
return await run_in_threadpool(dependant.call, **values)
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/starlette/concurrency.py", line 40, in run_in_threadpool
return await loop.run_in_executor(None, func, *args)
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/concurrent/futures/thread.py", line 57, in run
result = self.fn(*self.args, **self.kwargs)
File "/Users/str-kwml0020/projects/fastapi-crud-sqlite/./main.py", line 128, in add_city
session.execute('CALL addcity (?, ?)', ['One', 'Two'])
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/sqlalchemy/orm/session.py", line 1689, in execute
result = conn._execute_20(statement, params or {}, execution_options)
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1575, in _execute_20
args_10style, kwargs_10style = _distill_params_20(parameters)
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/sqlalchemy/engine/util.py", line 142, in _distill_params_20
raise exc.ArgumentError(
sqlalchemy.exc.ArgumentError: List argument must consist only of tuples or dictionaries
I have tried changing the params like below:
session.execute('CALL addcity (?, ?)', [('One', 'Two')])
The above code throws
Traceback (most recent call last):
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/uvicorn/protocols/http/h11_impl.py", line 369, in run_asgi
result = await app(self.scope, self.receive, self.send)
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/uvicorn/middleware/proxy_headers.py", line 59, in __call__
return await self.app(scope, receive, send)
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/fastapi/applications.py", line 208, in __call__
await super().__call__(scope, receive, send)
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/starlette/applications.py", line 112, in __call__
await self.middleware_stack(scope, receive, send)
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/starlette/middleware/errors.py", line 181, in __call__
raise exc from None
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/starlette/middleware/errors.py", line 159, in __call__
await self.app(scope, receive, _send)
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/starlette/exceptions.py", line 82, in __call__
raise exc from None
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/starlette/exceptions.py", line 71, in __call__
await self.app(scope, receive, sender)
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/starlette/routing.py", line 580, in __call__
await route.handle(scope, receive, send)
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/starlette/routing.py", line 241, in handle
await self.app(scope, receive, send)
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/starlette/routing.py", line 52, in app
response = await func(request)
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/fastapi/routing.py", line 219, in app
raw_response = await run_endpoint_function(
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/fastapi/routing.py", line 154, in run_endpoint_function
return await run_in_threadpool(dependant.call, **values)
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/starlette/concurrency.py", line 40, in run_in_threadpool
return await loop.run_in_executor(None, func, *args)
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/concurrent/futures/thread.py", line 57, in run
result = self.fn(*self.args, **self.kwargs)
File "/Users/str-kwml0020/projects/fastapi-crud-sqlite/./main.py", line 128, in add_city
session.execute('CALL addcity (?, ?)', [('One', 'Two')])
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/sqlalchemy/orm/session.py", line 1689, in execute
result = conn._execute_20(statement, params or {}, execution_options)
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1583, in _execute_20
return meth(self, args_10style, kwargs_10style, execution_options)
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/sqlalchemy/sql/elements.py", line 323, in _execute_on_connection
return connection._execute_clauseelement(
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1452, in _execute_clauseelement
ret = self._execute_context(
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1814, in _execute_context
self._handle_dbapi_exception(
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1995, in _handle_dbapi_exception
util.raise_(
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/sqlalchemy/util/compat.py", line 207, in raise_
raise exception
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1771, in _execute_context
self.dialect.do_execute(
File "/opt/anaconda3/envs/fastapi38/lib/python3.8/site-packages/sqlalchemy/engine/default.py", line 717, in do_execute
cursor.execute(statement, parameters)
sqlalchemy.exc.ProgrammingError: (psycopg2.errors.SyntaxError) syntax error at or near ","
LINE 1: CALL addcity (?, ?)
^
[SQL: CALL addcity (?, ?)]
(Background on this error at: https://sqlalche.me/e/14/f405)
When I checked SOF, most of the answers quoting the params as list of string. However, having strings inside the list as param didn't help either.
These are the library versions I have used:
fastapi==0.68.0
uvicorn==0.14.0
sqlalchemy_filters==0.12.0
SQLAlchemy==1.4.21
typing-extensions==3.10.0.0
Werkzeug==2.0.1
FastAPI-SQLAlchemy==0.2.1
Flask==2.0.1
Flask-SQLAlchemy==2.5.1
PyYaml
psycopg2-binary==2.9.1
As noted in a comment to the question, psycopg2 does not like the commit; in the SP. If you remove that then this will work with SQLAlchemy:
import sqlalchemy as sa
from sqlalchemy.orm import Session
engine = sa.create_engine("postgresql://scott:tiger#192.168.0.199/test")
with Session(engine) as session, session.begin():
session.execute(
sa.text("CALL addcity (:param1, :param2)"),
{"param1": "One", "param2": "Two"},
)
# automatically commits when the context manager exits (assuming no errors)
After #GordThompson and #AdrianKlaver asked some questions I have played around a bit and got this code as a solution
SP:
create or replace procedure addcity(
cname varchar(20),
state varchar(20)
)
language plpgsql
as $$
begin
insert into city
(cname, state)
values (cname, state);
# removed commit from the original SP
end;$$
Python code
cname = "Five"
state = "Six"
session.execute('CALL addcity (:cname, :state)', {'cname' : cname, 'state': state})
session.commit()
This works like a charm! Thanks #GordThompson and #AdrianKlaver. You guys saved my time!
Related
I searched for this error a lot, but I only find some with more information behind that like "FATAL: ...". Mine has none. It only says
sqlalchemy.exc.OperationalError: (psycopg2.OperationalError)
I have a postgres database inside a docker container that has set his port to the standard 5432.
I've created the container with the following command:
docker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -p 5432:5432 -d postgres
It is clean so no database created. The API should automatically create them.
I'm using Pycharm IDE, maybe it has something todo with that.
Traceback (most recent call last):
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 373, in run_asgi
result = await app(self.scope, self.receive, self.send)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\uvicorn\middleware\proxy_headers.py", line 75, in __call__
return await self.app(scope, receive, send)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\uvicorn\middleware\debug.py", line 96, in __call__
raise exc from None
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\uvicorn\middleware\debug.py", line 93, in __call__
await self.app(scope, receive, inner_send)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\fastapi\applications.py", line 208, in __call__
await super().__call__(scope, receive, send)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\starlette\applications.py", line 112, in __call__
await self.middleware_stack(scope, receive, send)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\starlette\middleware\errors.py", line 181, in __call__
raise exc from None
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\starlette\middleware\errors.py", line 159, in __call__
await self.app(scope, receive, _send)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\starlette\exceptions.py", line 82, in __call__
raise exc from None
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\starlette\exceptions.py", line 71, in __call__
await self.app(scope, receive, sender)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\starlette\routing.py", line 580, in __call__
await route.handle(scope, receive, send)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\starlette\routing.py", line 241, in handle
await self.app(scope, receive, send)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\starlette\routing.py", line 52, in app
response = await func(request)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\fastapi\routing.py", line 226, in app
raw_response = await run_endpoint_function(
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\fastapi\routing.py", line 159, in run_endpoint_function
return await dependant.call(**values)
File "C:\Users\Veril\PycharmProjects\partyapp-python\app\routers\v1\users.py", line 31, in create_user
session.commit()
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\orm\session.py", line 1428, in commit
self._transaction.commit(_to_root=self.future)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\orm\session.py", line 829, in commit
self._prepare_impl()
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\orm\session.py", line 808, in _prepare_impl
self.session.flush()
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\orm\session.py", line 3339, in flush
self._flush(objects)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\orm\session.py", line 3479, in _flush
transaction.rollback(_capture_exception=True)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\util\langhelpers.py", line 70, in __exit__
compat.raise_(
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\util\compat.py", line 207, in raise_
raise exception
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\orm\session.py", line 3439, in _flush
flush_context.execute()
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\orm\unitofwork.py", line 456, in execute
rec.execute(self)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\orm\unitofwork.py", line 630, in execute
util.preloaded.orm_persistence.save_obj(
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\orm\persistence.py", line 209, in save_obj
for (
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\orm\persistence.py", line 370, in _organize_states_for_save
for state, dict_, mapper, connection in _connections_for_states(
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\orm\persistence.py", line 1709, in _connections_for_states
connection = uowtransaction.transaction.connection(base_mapper)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\orm\session.py", line 626, in connection
return self._connection_for_bind(bind, execution_options)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\orm\session.py", line 735, in _connection_for_bind
conn = self._parent._connection_for_bind(bind, execution_options)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\orm\session.py", line 747, in _connection_for_bind
conn = bind.connect()
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\future\engine.py", line 419, in connect
return super(Engine, self).connect()
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\engine\base.py", line 3194, in connect
return self._connection_cls(self, close_with_result=close_with_result)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\engine\base.py", line 96, in __init__
else engine.raw_connection()
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\engine\base.py", line 3273, in raw_connection
return self._wrap_pool_connect(self.pool.connect, _connection)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\engine\base.py", line 3243, in _wrap_pool_connect
Connection._handle_dbapi_exception_noconnection(
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\engine\base.py", line 2097, in _handle_dbapi_exception_noconnection
util.raise_(
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\util\compat.py", line 207, in raise_
raise exception
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\engine\base.py", line 3240, in _wrap_pool_connect
return fn()
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\pool\base.py", line 310, in connect
return _ConnectionFairy._checkout(self)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\pool\base.py", line 868, in _checkout
fairy = _ConnectionRecord.checkout(pool)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\pool\base.py", line 476, in checkout
rec = pool._do_get()
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\pool\impl.py", line 146, in _do_get
self._dec_overflow()
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\util\langhelpers.py", line 70, in __exit__
compat.raise_(
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\util\compat.py", line 207, in raise_
raise exception
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\pool\impl.py", line 143, in _do_get
return self._create_connection()
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\pool\base.py", line 256, in _create_connection
return _ConnectionRecord(self)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\pool\base.py", line 371, in __init__
self.__connect()
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\pool\base.py", line 666, in __connect
pool.logger.debug("Error on connect(): %s", e)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\util\langhelpers.py", line 70, in __exit__
compat.raise_(
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\util\compat.py", line 207, in raise_
raise exception
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\pool\base.py", line 661, in __connect
self.dbapi_connection = connection = pool._invoke_creator(self)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\engine\create.py", line 590, in connect
return dialect.connect(*cargs, **cparams)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\engine\default.py", line 584, in connect
return self.dbapi.connect(*cargs, **cparams)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\psycopg2\__init__.py", line 122, in connect
conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
sqlalchemy.exc.OperationalError: (psycopg2.OperationalError)
(Background on this error at: https://sqlalche.me/e/14/e3q8)
This is my error that i get. My code looks like this:
main.py:
import os
import uvicorn
if __name__ == '__main__':
port = int(os.getenv("PORT"))
uvicorn.run("main:app", host='0.0.0.0', port=port, reload=True, debug=True, workers=3)
app/main.py:
import os
from fastapi import FastAPI
from .database import engine
from .routers import v1
engine.init_db()
port = int(os.getenv("PORT")) #Port is 8000
app = FastAPI()
app.include_router(v1.router, prefix="/v1")
app/database/engine.py: (referenced in the file above)
import os
from fastapi.security import HTTPBearer
from sqlmodel import create_engine, SQLModel, Session
DATABASE_URL = "postgresql+psycopg2://postgres:mysecretpassword#localhost:5432"
engine = create_engine(DATABASE_URL, echo=True)
token_auth_scheme = HTTPBearer()
async def init_db():
async with engine.begin() as conn:
# await conn.run_sync(SQLModel.metadata.drop_all)
await conn.run_sync(SQLModel.metadata.create_all)
async def get_session():
session = Session(engine)
try:
yield session
finally:
session.close()
The route "users" inside routers/v1/users.py:
from typing import Optional
from fastapi import APIRouter, Depends, HTTPException, Query, Path, Response, status
from pydantic import ValidationError
from sqlalchemy.exc import IntegrityError
from sqlalchemy.sql.functions import concat
from sqlalchemy import func
from sqlmodel import Session, select, col
from starlette import status
from app.database import models
from app.database.authentication import VerifyToken
from app.database.engine import get_session, token_auth_scheme
router = APIRouter()
#router.post("", status_code=status.HTTP_201_CREATED, response_model=models.UserRead,
response_model_exclude_none=True, name="Create User", tags=["users"])
async def create_user(user_data: models.UserCreate,
session: Session = Depends(get_session)):
try:
new_user = models.User(**dict(user_data))
session.add(new_user)
session.commit()
session.refresh(new_user)
return new_user
except IntegrityError:
session.rollback()
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="IntegrityError")
except ValidationError:
session.rollback()
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail="ValidationError")
The models.User:
class UserBase(SQLModel):
id: str
username: Optional[str]
country_code: Optional[str]
phone: Optional[str]
class Config:
allow_population_by_field_name = True
class User(UserBase, table=True):
__tablename__ = 'users'
id: str = Field(primary_key=True)
username: Optional[str] = Field(sa_column=Column('username', VARCHAR(length=50), unique=True, default=None))
phone: Optional[str] = Field(sa_column=Column('phone', VARCHAR(length=20), unique=True, default=None))
I hope that this is everything you guys need to find something. If you need something else contact me.
Best regards
Colin
EDIT:
After I changed the link from `postgresql+psycopg2` to `postgresql+asyncpg` I get a new error:
ERROR: Exception in ASGI application
Traceback (most recent call last):
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 373, in run_asgi
result = await app(self.scope, self.receive, self.send)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\uvicorn\middleware\proxy_headers.py", line 75, in __call__
return await self.app(scope, receive, send)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\uvicorn\middleware\debug.py", line 96, in __call__
raise exc from None
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\uvicorn\middleware\debug.py", line 93, in __call__
await self.app(scope, receive, inner_send)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\fastapi\applications.py", line 208, in __call__
await super().__call__(scope, receive, send)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\starlette\applications.py", line 112, in __call__
await self.middleware_stack(scope, receive, send)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\starlette\middleware\errors.py", line 181, in __call__
raise exc from None
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\starlette\middleware\errors.py", line 159, in __call__
await self.app(scope, receive, _send)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\starlette\exceptions.py", line 82, in __call__
raise exc from None
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\starlette\exceptions.py", line 71, in __call__
await self.app(scope, receive, sender)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\starlette\routing.py", line 580, in __call__
await route.handle(scope, receive, send)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\starlette\routing.py", line 241, in handle
await self.app(scope, receive, send)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\starlette\routing.py", line 52, in app
response = await func(request)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\fastapi\routing.py", line 226, in app
raw_response = await run_endpoint_function(
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\fastapi\routing.py", line 159, in run_endpoint_function
return await dependant.call(**values)
File "C:\Users\Veril\PycharmProjects\partyapp-python\app\routers\v1\users.py", line 26, in create_user
session.commit()
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\orm\session.py", line 1428, in commit
self._transaction.commit(_to_root=self.future)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\orm\session.py", line 829, in commit
self._prepare_impl()
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\orm\session.py", line 808, in _prepare_impl
self.session.flush()
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\orm\session.py", line 3339, in flush
self._flush(objects)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\orm\session.py", line 3479, in _flush
transaction.rollback(_capture_exception=True)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\util\langhelpers.py", line 70, in __exit__
compat.raise_(
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\util\compat.py", line 207, in raise_
raise exception
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\orm\session.py", line 3439, in _flush
flush_context.execute()
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\orm\unitofwork.py", line 456, in execute
rec.execute(self)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\orm\unitofwork.py", line 630, in execute
util.preloaded.orm_persistence.save_obj(
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\orm\persistence.py", line 209, in save_obj
for (
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\orm\persistence.py", line 370, in _organize_states_for_save
for state, dict_, mapper, connection in _connections_for_states(
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\orm\persistence.py", line 1709, in _connections_for_states
connection = uowtransaction.transaction.connection(base_mapper)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\orm\session.py", line 626, in connection
return self._connection_for_bind(bind, execution_options)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\orm\session.py", line 735, in _connection_for_bind
conn = self._parent._connection_for_bind(bind, execution_options)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\orm\session.py", line 747, in _connection_for_bind
conn = bind.connect()
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\future\engine.py", line 419, in connect
return super(Engine, self).connect()
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\engine\base.py", line 3194, in connect
return self._connection_cls(self, close_with_result=close_with_result)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\engine\base.py", line 96, in __init__
else engine.raw_connection()
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\engine\base.py", line 3273, in raw_connection
return self._wrap_pool_connect(self.pool.connect, _connection)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\engine\base.py", line 3240, in _wrap_pool_connect
return fn()
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\pool\base.py", line 310, in connect
return _ConnectionFairy._checkout(self)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\pool\base.py", line 868, in _checkout
fairy = _ConnectionRecord.checkout(pool)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\pool\base.py", line 476, in checkout
rec = pool._do_get()
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\pool\impl.py", line 146, in _do_get
self._dec_overflow()
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\util\langhelpers.py", line 70, in __exit__
compat.raise_(
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\util\compat.py", line 207, in raise_
raise exception
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\pool\impl.py", line 143, in _do_get
return self._create_connection()
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\pool\base.py", line 256, in _create_connection
return _ConnectionRecord(self)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\pool\base.py", line 371, in __init__
self.__connect()
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\pool\base.py", line 666, in __connect
pool.logger.debug("Error on connect(): %s", e)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\util\langhelpers.py", line 70, in __exit__
compat.raise_(
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\util\compat.py", line 207, in raise_
raise exception
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\pool\base.py", line 661, in __connect
self.dbapi_connection = connection = pool._invoke_creator(self)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\engine\create.py", line 590, in connect
return dialect.connect(*cargs, **cparams)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\engine\default.py", line 584, in connect
return self.dbapi.connect(*cargs, **cparams)
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\dialects\postgresql\asyncpg.py", line 748, in connect
await_only(self.asyncpg.connect(*arg, **kw)),
File "C:\Users\Veril\PycharmProjects\partyapp-python\venv\lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 61, in await_only
raise exc.MissingGreenlet(
sqlalchemy.exc.MissingGreenlet: greenlet_spawn has not been called; can't call await_() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/14/xd2s)
EDIT 2:
If I use my local postgres database in docker i get this error. If I use my extern database from Heroku it works perfectly fine!
EDIT 3:
So apparently it won't work with my local docker postgres database. Now I am using my production database over heroku (so externally) and everything works with psycopg2. I didn't found the error why it won't let me use my local db but whatever.
Even though I can see that you are using default port, maybe this can help to somebody with the same problem.
For me the problem was in explicit port definition - as I'm running two different postgres DB and (both from containers), one of them I set to listen to 5433 port - and this gives me exact same problem, so instead
SQLALCHEMY_DATABASE_URL = "postgresql://postgres:password#localhost/fastapi"
I just put:
SQLALCHEMY_DATABASE_URL = "postgresql://postgres:password#localhost:5433/fastapi"
Problem solved right away.
I have some legacy code that has a polymorphic base class definition and two sub classes.
The entity definitions are below.
class Field(Base):
__tablename__ = "field"
field_parent = Column(String(64), index=True)
controller_id = Column(ForeignKey('controller.id'))
controller = relationship("Controller")
node_id = Column(ForeignKey("node.id"))
__mapper_args__ = {"polymorphic_on": field_parent}
class ControllerField(Field):
__mapper_args__ = {"polymorphic_identity": "controller"}
class NodeField(Field):
__mapper_args__ = {"polymorphic_identity": "node"}
class Controller:
__tablename__ = "controller"
class Node:
__tablename__ = "node"
Some example data from my local DB.
enter image description here
I'm trying to query the 'controller' table and SQLAlchemy is trying to load all the class's relationships (my assumption). When it gets to the polymorphic subclass the query fails because the 'field' table contains foreign key references to both the 'controller' and 'node' tables and because the latter is supposed to be of type 'node' it still has an FK to the 'controller' table and thus the identity is not the right type. It seems like SQLAlchemy doesn't like this in the current configuration. The stacktrace can be seen below.
File "/usr/local/lib/python3.9/site-packages/uvicorn/protocols/http/h11_impl.py", line 396, in run_asgi
result = await app(self.scope, self.receive, self.send)
File "/usr/local/lib/python3.9/site-packages/uvicorn/middleware/proxy_headers.py", line 45, in __call__
return await self.app(scope, receive, send)
File "/usr/local/lib/python3.9/site-packages/fastapi/applications.py", line 199, in __call__
await super().__call__(scope, receive, send)
File "/usr/local/lib/python3.9/site-packages/starlette/applications.py", line 112, in __call__
await self.middleware_stack(scope, receive, send)
File "/usr/local/lib/python3.9/site-packages/starlette/middleware/errors.py", line 181, in __call__
raise exc from None
File "/usr/local/lib/python3.9/site-packages/starlette/middleware/errors.py", line 159, in __call__
await self.app(scope, receive, _send)
File "/usr/local/lib/python3.9/site-packages/starlette/middleware/cors.py", line 78, in __call__
await self.app(scope, receive, send)
File "/usr/local/lib/python3.9/site-packages/starlette/exceptions.py", line 82, in __call__
raise exc from None
File "/usr/local/lib/python3.9/site-packages/starlette/exceptions.py", line 71, in __call__
await self.app(scope, receive, sender)
File "/usr/local/lib/python3.9/site-packages/starlette/routing.py", line 580, in __call__
await route.handle(scope, receive, send)
File "/usr/local/lib/python3.9/site-packages/starlette/routing.py", line 390, in handle
await self.app(scope, receive, send)
File "/usr/local/lib/python3.9/site-packages/fastapi/applications.py", line 199, in __call__
await super().__call__(scope, receive, send)
File "/usr/local/lib/python3.9/site-packages/starlette/applications.py", line 112, in __call__
await self.middleware_stack(scope, receive, send)
File "/usr/local/lib/python3.9/site-packages/starlette/middleware/errors.py", line 181, in __call__
raise exc from None
File "/usr/local/lib/python3.9/site-packages/starlette/middleware/errors.py", line 159, in __call__
await self.app(scope, receive, _send)
File "/usr/local/lib/python3.9/site-packages/starlette/middleware/cors.py", line 78, in __call__
await self.app(scope, receive, send)
File "/usr/local/lib/python3.9/site-packages/starlette/exceptions.py", line 82, in __call__
raise exc from None
File "/usr/local/lib/python3.9/site-packages/starlette/exceptions.py", line 71, in __call__
await self.app(scope, receive, sender)
File "/usr/local/lib/python3.9/site-packages/starlette/routing.py", line 580, in __call__
await route.handle(scope, receive, send)
File "/usr/local/lib/python3.9/site-packages/starlette/routing.py", line 241, in handle
await self.app(scope, receive, send)
File "/usr/local/lib/python3.9/site-packages/starlette/routing.py", line 52, in app
response = await func(request)
File "/usr/local/lib/python3.9/site-packages/fastapi/routing.py", line 201, in app
raw_response = await run_endpoint_function(
File "/usr/local/lib/python3.9/site-packages/fastapi/routing.py", line 150, in run_endpoint_function
return await run_in_threadpool(dependant.call, **values)
File "/usr/local/lib/python3.9/site-packages/starlette/concurrency.py", line 40, in run_in_threadpool
return await loop.run_in_executor(None, func, *args)
File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 58, in run
result = self.fn(*self.args, **self.kwargs)
File "/usr/src/app/./app/subapp/shim/v2/endpoints/controller.py", line 25, in get
return Wrapper(data=service.get(id=id, controller_category=controllerCategory, condensed=condensed))
File "/usr/src/app/./app/subapp/shim/services/controller_service.py", line 23, in get
"controller": self.__append_nodes(controller.dict(logged_in_user=self.__logged_in_user))
File "/usr/src/app/./app/database/base_new.py", line 28, in dict
rs = getattr(self, relationship.key)
File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/attributes.py", line 481, in __get__
return self.impl.get(state, dict_)
File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/attributes.py", line 926, in get
value = self._fire_loader_callables(state, key, passive)
File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/attributes.py", line 962, in _fire_loader_callables
return self.callable_(state, passive)
File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/strategies.py", line 892, in _load_for_state
return self._emit_lazyload(
File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/strategies.py", line 1056, in _emit_lazyload
result = result.unique().scalars().all()
File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/result.py", line 1319, in all
return self._allrows()
File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/result.py", line 400, in _allrows
rows = self._fetchall_impl()
File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/result.py", line 1232, in _fetchall_impl
return self._real_result._fetchall_impl()
File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/result.py", line 1626, in _fetchall_impl
return list(self.iterator)
File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/loading.py", line 124, in chunks
rows = [proc(row) for row in fetch]
File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/loading.py", line 124, in <listcomp>
rows = [proc(row) for row in fetch]
File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/loading.py", line 1274, in polymorphic_instance
raise sa_exc.InvalidRequestError(
sqlalchemy.exc.InvalidRequestError: Row with identity key (<class 'app.database.models.field.Field'>, (150,), None) can't be loaded into an object; the polymorphic discriminator column 'field.field_parent' refers to mapped class NodeField->field, which is not a sub-mapper of the requested mapped class ControllerField->field
If I delete the reference to the 'controller' table on the instance with identity 'node' the queries run as expected. As this is legacy code I can't just delete the extra FK references as we don't know what will break if we do this. Is there a way that I can tell SQLAlchemy to load the correct definition without looking at the FK reference or something?
Extra info:
FastAPI Docker Container with a MySQL database
Python 3.8
SQLAlchemy 1.4.21
I've come across the same stuff here, hence I'm going through your post ;) The obvious solution is to select a common ancestor class defining the concrete polymorphic identity via filter or smth.
I just had the same issue as well and found a very simple solution: the base class needs also to have a polymorphic identity (e.g. 'base'). Set this value to be the default value of 'field_parent'.
The new code looks like this:
class Field(Base):
__tablename__ = "field"
field_parent = Column(String(64), index=True, default="base")
__mapper_args__ = {"polymorphic_on": field_parent,
"polymorphic_identity": "base"}
controller_id = Column(ForeignKey("controller.id"))
controller = relationship("Controller")
node_id = Column(ForeignKey("node.id"))
I'm using FastAPI & SQLModel to insert data into SQLite database (I'm posting a few fields, then SQLModel adds UUID and datetime fields and inserts into db).
While posting data to FastAPI, I occasionally get ValueError:
ValueError: badly formed hexadecimal UUID string
I don't think there's a problem with the data I'm sending as I'm not sending id field, so maybe I misconfigured my SQLModel?
Models:
# -*- coding: utf-8 -*-
import uuid
from typing import Optional
from datetime import datetime, date
from pydantic import UUID4, HttpUrl
from sqlmodel import Field, SQLModel
class EventBase(SQLModel):
title: str
text: str
date: date
URL: HttpUrl
category: Optional[str] = Field(default=None)
class Event(EventBase, table=True):
id: UUID4 = Field(default_factory=uuid.uuid4, primary_key=True)
created_at: datetime = Field(default_factory=datetime.utcnow)
Edit: decided to try this approach replacing UUID4 with uuid.UUID, but it didn't work as well:
Uvicorn debug:
INFO: 127.0.0.1:53312 - "POST /speeches/ HTTP/1.1" 500 Internal Server Error
ERROR: Exception in ASGI application
Traceback (most recent call last):
File "c:\github\speeches-api\env\lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 373, in run_asgi
result = await app(self.scope, self.receive, self.send)
File "c:\github\speeches-api\env\lib\site-packages\uvicorn\middleware\proxy_headers.py", line 75, in __call__
return await self.app(scope, receive, send)
File "c:\github\speeches-api\env\lib\site-packages\uvicorn\middleware\debug.py", line 96, in __call__
raise exc from None
File "c:\github\speeches-api\env\lib\site-packages\uvicorn\middleware\debug.py", line 93, in __call__
await self.app(scope, receive, inner_send)
File "c:\github\speeches-api\env\lib\site-packages\fastapi\applications.py", line 208, in __call__
await super().__call__(scope, receive, send)
File "c:\github\speeches-api\env\lib\site-packages\starlette\applications.py", line 112, in __call__
await self.middleware_stack(scope, receive, send)
File "c:\github\speeches-api\env\lib\site-packages\starlette\middleware\errors.py", line 181, in __call__
raise exc
File "c:\github\speeches-api\env\lib\site-packages\starlette\middleware\errors.py", line 159, in __call__
await self.app(scope, receive, _send)
File "c:\github\speeches-api\env\lib\site-packages\starlette\exceptions.py", line 82, in __call__
raise exc
File "c:\github\speeches-api\env\lib\site-packages\starlette\exceptions.py", line 71, in __call__
await self.app(scope, receive, sender)
File "c:\github\speeches-api\env\lib\site-packages\starlette\routing.py", line 656, in __call__
await route.handle(scope, receive, send)
File "c:\github\speeches-api\env\lib\site-packages\starlette\routing.py", line 259, in handle
await self.app(scope, receive, send)
File "c:\github\speeches-api\env\lib\site-packages\starlette\routing.py", line 61, in app
response = await func(request)
File "c:\github\speeches-api\env\lib\site-packages\fastapi\routing.py", line 226, in app
raw_response = await run_endpoint_function(
File "c:\github\speeches-api\env\lib\site-packages\fastapi\routing.py", line 161, in run_endpoint_function
return await run_in_threadpool(dependant.call, **values)
File "c:\github\speeches-api\env\lib\site-packages\starlette\concurrency.py", line 39, in run_in_threadpool
return await anyio.to_thread.run_sync(func, *args)
File "c:\github\speeches-api\env\lib\site-packages\anyio\to_thread.py", line 28, in run_sync
return await get_asynclib().run_sync_in_worker_thread(func, *args, cancellable=cancellable,
File "c:\github\speeches-api\env\lib\site-packages\anyio\_backends\_asyncio.py", line 818, in run_sync_in_worker_thread
return await future
File "c:\github\speeches-api\env\lib\site-packages\anyio\_backends\_asyncio.py", line 754, in run
result = context.run(func, *args)
File ".\app\main.py", line 29, in create_events
session.refresh(event)
File "c:\github\speeches-api\env\lib\site-packages\sqlalchemy\orm\session.py", line 2315, in refresh
loading.load_on_ident(
File "c:\github\speeches-api\env\lib\site-packages\sqlalchemy\orm\loading.py", line 407, in load_on_ident
return load_on_pk_identity(
File "c:\github\speeches-api\env\lib\site-packages\sqlalchemy\orm\loading.py", line 541, in load_on_pk_identity
return result.one()
File "c:\github\speeches-api\env\lib\site-packages\sqlalchemy\engine\result.py", line 1407, in one
return self._only_one_row(
File "c:\github\speeches-api\env\lib\site-packages\sqlalchemy\engine\result.py", line 558, in _only_one_row
row = onerow(hard_close=True)
File "c:\github\speeches-api\env\lib\site-packages\sqlalchemy\engine\result.py", line 1271, in _fetchone_impl
return self._real_result._fetchone_impl(hard_close=hard_close)
File "c:\github\speeches-api\env\lib\site-packages\sqlalchemy\engine\result.py", line 1674, in _fetchone_impl
row = next(self.iterator, _NO_ROW)
File "c:\github\speeches-api\env\lib\site-packages\sqlalchemy\orm\loading.py", line 147, in chunks
fetch = cursor._raw_all_rows()
File "c:\github\speeches-api\env\lib\site-packages\sqlalchemy\engine\result.py", line 392, in _raw_all_rows
return [make_row(row) for row in rows]
File "c:\github\speeches-api\env\lib\site-packages\sqlalchemy\engine\result.py", line 392, in <listcomp>
return [make_row(row) for row in rows]
File "c:\github\speeches-api\env\lib\site-packages\sqlalchemy\sql\type_api.py", line 1537, in process
return process_value(value, dialect)
File "c:\github\speeches-api\env\lib\site-packages\sqlmodel\sql\sqltypes.py", line 59, in process_result_value
value = uuid.UUID(value)
File "C:\Users\user\AppData\Local\Programs\Python\Python38\lib\uuid.py", line 169, in __init__
raise ValueError('badly formed hexadecimal UUID string')
ValueError: badly formed hexadecimal UUID string
I learnt that the problem was described in this issue: data validation 'works except whenever the uuid.uuid4 default factory creates a UUID with a hexstring that starts with a zero.'
Proposed (temp) solution is posted below in the comments, by chriswhite199:
adjusted for my case:
def new_uuid() -> uuid.UUID:
# Note: Work around UUIDs with leading zeros: https://github.com/tiangolo/sqlmodel/issues/25
# by making sure uuid str does not start with a leading 0
val = uuid.uuid4()
while val.hex[0] == '0':
val = uuid.uuid4()
return val
class Event(EventBase, table=True):
id: UUID4 = Field(default_factory=new_uuid, primary_key=True)
created_at: datetime = Field(default_factory=datetime.utcnow)
I think you need to do a str(uuid.uuid4()) in default factory
So I have an image which I read the contents off of through .read() which is part of the UploadFile class and I believe it reads in bytes https://fastapi.tiangolo.com/tutorial/request-files/. To convert the bytes objects into bytea data type I used psycopg2.Binary() but I got an error message saying KeyError: '$fu'
This is my code for the portion that's reading off the bytes from the image and trying to store it in Postgresql through the bytea data type
image_array = []
for image in images_upload:
contents = await image.read()
image_array.append(contents)
# add image validation
for (permission, text, characteristics, image) in zip(p, c, t, image_array):
query = ("insert into images(permissions,text,characteristics,date_created,user_id,img)"
f"values('{permission}','{text}',"
f"'{characteristics}'"
f",{func.now()},{result[0]['id']}"
f",'{psycopg2.Binary(image)}')")
await database.execute(query=query)
Here's the trace
INFO: 127.0.0.1:53168 - "POST /add/?api_key=stringstring&texts=string&characteristics=string&permissions=string HTTP/1.1" 500 Internal Server Error
ERROR: Exception in ASGI application
Traceback (most recent call last):
File "/Users/admin/Library/Caches/pypoetry/virtualenvs/backend-DSfoN2Wn-py3.9/lib/python3.9/site-packages/uvicorn/protocols/http/h11_impl.py", line 396, in run_asgi
result = await app(self.scope, self.receive, self.send)
File "/Users/admin/Library/Caches/pypoetry/virtualenvs/backend-DSfoN2Wn-py3.9/lib/python3.9/site-packages/uvicorn/middleware/proxy_headers.py", line 45, in __call__
return await self.app(scope, receive, send)
File "/Users/admin/Library/Caches/pypoetry/virtualenvs/backend-DSfoN2Wn-py3.9/lib/python3.9/site-packages/fastapi/applications.py", line 199, in __call__
await super().__call__(scope, receive, send)
File "/Users/admin/Library/Caches/pypoetry/virtualenvs/backend-DSfoN2Wn-py3.9/lib/python3.9/site-packages/starlette/applications.py", line 111, in __call__
await self.middleware_stack(scope, receive, send)
File "/Users/admin/Library/Caches/pypoetry/virtualenvs/backend-DSfoN2Wn-py3.9/lib/python3.9/site-packages/starlette/middleware/errors.py", line 181, in __call__
raise exc from None
File "/Users/admin/Library/Caches/pypoetry/virtualenvs/backend-DSfoN2Wn-py3.9/lib/python3.9/site-packages/starlette/middleware/errors.py", line 159, in __call__
await self.app(scope, receive, _send)
File "/Users/admin/Library/Caches/pypoetry/virtualenvs/backend-DSfoN2Wn-py3.9/lib/python3.9/site-packages/starlette/exceptions.py", line 82, in __call__
raise exc from None
File "/Users/admin/Library/Caches/pypoetry/virtualenvs/backend-DSfoN2Wn-py3.9/lib/python3.9/site-packages/starlette/exceptions.py", line 71, in __call__
await self.app(scope, receive, sender)
File "/Users/admin/Library/Caches/pypoetry/virtualenvs/backend-DSfoN2Wn-py3.9/lib/python3.9/site-packages/starlette/routing.py", line 566, in __call__
await route.handle(scope, receive, send)
File "/Users/admin/Library/Caches/pypoetry/virtualenvs/backend-DSfoN2Wn-py3.9/lib/python3.9/site-packages/starlette/routing.py", line 227, in handle
await self.app(scope, receive, send)
File "/Users/admin/Library/Caches/pypoetry/virtualenvs/backend-DSfoN2Wn-py3.9/lib/python3.9/site-packages/starlette/routing.py", line 41, in app
response = await func(request)
File "/Users/admin/Library/Caches/pypoetry/virtualenvs/backend-DSfoN2Wn-py3.9/lib/python3.9/site-packages/fastapi/routing.py", line 201, in app
raw_response = await run_endpoint_function(
File "/Users/admin/Library/Caches/pypoetry/virtualenvs/backend-DSfoN2Wn-py3.9/lib/python3.9/site-packages/fastapi/routing.py", line 148, in run_endpoint_function
return await dependant.call(**values)
File "./app/controllers/add.py", line 49, in add_images
await database.execute(query=query)
File "/Users/admin/Library/Caches/pypoetry/virtualenvs/backend-DSfoN2Wn-py3.9/lib/python3.9/site-packages/databases/core.py", line 161, in execute
return await connection.execute(query, values)
File "/Users/admin/Library/Caches/pypoetry/virtualenvs/backend-DSfoN2Wn-py3.9/lib/python3.9/site-packages/databases/core.py", line 263, in execute
return await self._connection.execute(built_query)
File "/Users/admin/Library/Caches/pypoetry/virtualenvs/backend-DSfoN2Wn-py3.9/lib/python3.9/site-packages/databases/backends/postgres.py", line 188, in execute
query, args, result_columns = self._compile(query)
File "/Users/admin/Library/Caches/pypoetry/virtualenvs/backend-DSfoN2Wn-py3.9/lib/python3.9/site-packages/databases/backends/postgres.py", line 221, in _compile
compiled_query = compiled.string % mapping
KeyError: '$fu'
I got an error on my Cloud Run, in my log it said Broken Pipe error, and when I check it which line that got an error on my Code, it on my db2.comit(). My cloud run always run well from 6 month ago without any error, but now got this error.
So here are the detail from the log.
Traceback (most recent call last):
File "/usr/local/lib/python3.8/site-packages/uvicorn/protocols/http/httptools_impl.py", line 385, in run_asgi
result = await app(self.scope, self.receive, self.send)
File "/usr/local/lib/python3.8/site-packages/uvicorn/middleware/proxy_headers.py", line 45, in __call__
return await self.app(scope, receive, send)
File "/usr/local/lib/python3.8/site-packages/fastapi/applications.py", line 190, in __call__
await super().__call__(scope, receive, send)
File "/usr/local/lib/python3.8/site-packages/starlette/applications.py", line 111, in __call__
await self.middleware_stack(scope, receive, send)
File "/usr/local/lib/python3.8/site-packages/starlette/middleware/errors.py", line 181, in __call__
raise exc from None
File "/usr/local/lib/python3.8/site-packages/starlette/middleware/errors.py", line 159, in __call__
await self.app(scope, receive, _send)
File "/usr/local/lib/python3.8/site-packages/starlette/middleware/cors.py", line 78, in __call__
await self.app(scope, receive, send)
File "/usr/local/lib/python3.8/site-packages/starlette/exceptions.py", line 82, in __call__
raise exc from None
File "/usr/local/lib/python3.8/site-packages/starlette/exceptions.py", line 71, in __call__
await self.app(scope, receive, sender)
File "/usr/local/lib/python3.8/site-packages/starlette/routing.py", line 566, in __call__
await route.handle(scope, receive, send)
File "/usr/local/lib/python3.8/site-packages/starlette/routing.py", line 227, in handle
await self.app(scope, receive, send)
File "/usr/local/lib/python3.8/site-packages/starlette/routing.py", line 41, in app
response = await func(request)
File "/usr/local/lib/python3.8/site-packages/fastapi/routing.py", line 188, in app
raw_response = await run_endpoint_function(
File "/usr/local/lib/python3.8/site-packages/fastapi/routing.py", line 135, in run_endpoint_function
return await dependant.call(**values)
File "/app/api/endpoints.py", line 48, in detect
db2.commit()
File "/usr/local/lib/python3.8/site-packages/sqlalchemy/orm/session.py", line 1042, in commit
self.transaction.commit()
File "/usr/local/lib/python3.8/site-packages/sqlalchemy/orm/session.py", line 504, in commit
self._prepare_impl()
File "/usr/local/lib/python3.8/site-packages/sqlalchemy/orm/session.py", line 483, in _prepare_impl
self.session.flush()
File "/usr/local/lib/python3.8/site-packages/sqlalchemy/orm/session.py", line 2523, in flush
self._flush(objects)
File "/usr/local/lib/python3.8/site-packages/sqlalchemy/orm/session.py", line 2664, in _flush
transaction.rollback(_capture_exception=True)
File "/usr/local/lib/python3.8/site-packages/sqlalchemy/util/langhelpers.py", line 68, in __exit__
compat.raise_(
File "/usr/local/lib/python3.8/site-packages/sqlalchemy/util/compat.py", line 182, in raise_
raise exception
File "/usr/local/lib/python3.8/site-packages/sqlalchemy/orm/session.py", line 2624, in _flush
flush_context.execute()
File "/usr/local/lib/python3.8/site-packages/sqlalchemy/orm/unitofwork.py", line 422, in execute
rec.execute(self)
File "/usr/local/lib/python3.8/site-packages/sqlalchemy/orm/unitofwork.py", line 586, in execute
persistence.save_obj(
File "/usr/local/lib/python3.8/site-packages/sqlalchemy/orm/persistence.py", line 205, in save_obj
for (
File "/usr/local/lib/python3.8/site-packages/sqlalchemy/orm/persistence.py", line 373, in _organize_states_for_save
for state, dict_, mapper, connection in _connections_for_states(
File "/usr/local/lib/python3.8/site-packages/sqlalchemy/orm/persistence.py", line 1602, in _connections_for_states
connection = uowtransaction.transaction.connection(base_mapper)
File "/usr/local/lib/python3.8/site-packages/sqlalchemy/orm/session.py", line 314, in connection
return self._connection_for_bind(bind, execution_options)
File "/usr/local/lib/python3.8/site-packages/sqlalchemy/orm/session.py", line 421, in _connection_for_bind
conn = self._parent._connection_for_bind(bind, execution_options)
File "/usr/local/lib/python3.8/site-packages/sqlalchemy/orm/session.py", line 433, in _connection_for_bind
conn = bind._contextual_connect()
File "/usr/local/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 2304, in _contextual_connect
self._wrap_pool_connect(self.pool.connect, None),
File "/usr/local/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 2338, in _wrap_pool_connect
return fn()
File "/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 364, in connect
return _ConnectionFairy._checkout(self)
File "/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 809, in _checkout
result = pool._dialect.do_ping(fairy.connection)
File "/usr/local/lib/python3.8/site-packages/sqlalchemy/engine/default.py", line 560, in do_ping
cursor.execute(self._dialect_specific_select_one)
File "/usr/local/lib/python3.8/site-packages/pg8000/core.py", line 340, in execute
self._c.execute_unnamed(self, "begin transaction")
File "/usr/local/lib/python3.8/site-packages/pg8000/core.py", line 1214, in execute_unnamed
self.handle_messages(cursor)
File "/usr/local/lib/python3.8/site-packages/pg8000/core.py", line 1377, in handle_messages
code, data_len = ci_unpack(self._read(5))
struct.error: unpack_from requires a buffer of at least 5 bytes for unpacking 5 bytes at offset 0 (actual buffer size is 0)
And this is my line of code that occurs the error.
except Exception as e: # noqa
log = orm.LogPredictStatus(customer_id=customer_id, status_code=500, car_attribute=car.dict(), price=None, source='TEST', created_at=time_zone_jakarta)
db2.add(log)
db2.commit()
raise HTTPException(
status_code=500,
detail=str(e),
)