gino icon indicating copy to clipboard operation
gino copied to clipboard

AttributeError: 'asyncpg.pgproto.pgproto.UUID' object has no attribute 'replace'

Open PetrMixayloff opened this issue 5 years ago • 3 comments

  • GINO version: 1.0.1
  • Python version: 3.8.2
  • asyncpg version: 0.20.1
  • PostgreSQL version: 12.3 (Ubuntu 12.3-1.pgdg20.04+1)

Description

I'm trying to use UUID value as unique Id in my model

from . import db
from uuid import uuid4
from sqlalchemy.dialects.postgresql import UUID


class User(db.Model):
    __tablename__ = "users"

    id = db.Column(UUID(as_uuid=True), primary_key=True, unique=True, index=True, nullable=False, default=uuid4)
    login = db.Column(db.String(255), nullable=False, unique=True)
    password = db.Column(db.String(255), nullable=True)
    full_name = db.Column(db.String(255))
    last_login = db.Column(db.DateTime, nullable=True)
    is_superuser = db.Column(db.Boolean, nullable=False, default=False)
    is_staff = db.Column(db.Boolean, nullable=False, default=True)
    remark = db.Column(db.String)

My controller is

class UserModel(BaseModel):
    login: str
    password: str
    full_name: str
    is_superuser: bool = False
    is_staff: bool = True
    remark: str = None


@router.post("/users")
async def add_user(user: UserModel):

    rv = await User.create(login=user.login,
                           password=user.password,
                           full_name=user.full_name,
                           is_superuser=user.is_superuser,
                           is_staff=user.is_staff,
                           remark=user.remark
                           )
    return rv.to_dict()

What I Did

When I'm trying to post a new user to db via swagger UI I got this error:

INFO:     127.0.0.1:38548 - "POST /users HTTP/1.1" 500 Internal Server Error
ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "/home/petr/crm/.venv/lib/python3.8/site-packages/uvicorn/protocols/http/httptools_impl.py", line 386, in run_asgi
    result = await app(self.scope, self.receive, self.send)
  File "/home/petr/crm/.venv/lib/python3.8/site-packages/uvicorn/middleware/proxy_headers.py", line 45, in __call__
    return await self.app(scope, receive, send)
  File "/home/petr/crm/.venv/lib/python3.8/site-packages/fastapi/applications.py", line 181, in __call__
    await super().__call__(scope, receive, send)
  File "/home/petr/crm/.venv/lib/python3.8/site-packages/starlette/applications.py", line 111, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/home/petr/crm/.venv/lib/python3.8/site-packages/starlette/middleware/errors.py", line 181, in __call__
    raise exc from None
  File "/home/petr/crm/.venv/lib/python3.8/site-packages/starlette/middleware/errors.py", line 159, in __call__
    await self.app(scope, receive, _send)
  File "/home/petr/crm/.venv/lib/python3.8/site-packages/gino_starlette.py", line 79, in __call__
    await self.app(scope, receive, send)
  File "/home/petr/crm/.venv/lib/python3.8/site-packages/starlette/exceptions.py", line 82, in __call__
    raise exc from None
  File "/home/petr/crm/.venv/lib/python3.8/site-packages/starlette/exceptions.py", line 71, in __call__
    await self.app(scope, receive, sender)
  File "/home/petr/crm/.venv/lib/python3.8/site-packages/starlette/routing.py", line 566, in __call__
    await route.handle(scope, receive, send)
  File "/home/petr/crm/.venv/lib/python3.8/site-packages/starlette/routing.py", line 227, in handle
    await self.app(scope, receive, send)
  File "/home/petr/crm/.venv/lib/python3.8/site-packages/starlette/routing.py", line 41, in app
    response = await func(request)
  File "/home/petr/crm/.venv/lib/python3.8/site-packages/fastapi/routing.py", line 196, in app
    raw_response = await run_endpoint_function(
  File "/home/petr/crm/.venv/lib/python3.8/site-packages/fastapi/routing.py", line 147, in run_endpoint_function
    return await dependant.call(**values)
  File "./src/crm/views/users.py", line 30, in add_user
    rv = await User.create(login=user.login,
  File "/home/petr/crm/.venv/lib/python3.8/site-packages/gino/crud.py", line 444, in _create_without_instance
    return await cls(**values)._create(bind=bind, timeout=timeout)
  File "/home/petr/crm/.venv/lib/python3.8/site-packages/gino/crud.py", line 478, in _create
    for k, v in row.items():
  File "/home/petr/crm/.venv/lib/python3.8/site-packages/sqlalchemy/engine/result.py", line 207, in items
    return [(key, self[key]) for key in self.keys()]
  File "/home/petr/crm/.venv/lib/python3.8/site-packages/sqlalchemy/engine/result.py", line 207, in <listcomp>
    return [(key, self[key]) for key in self.keys()]
  File "/home/petr/crm/.venv/lib/python3.8/site-packages/sqlalchemy/dialects/postgresql/base.py", line 1328, in process
    value = _python_UUID(value)
  File "/usr/lib/python3.8/uuid.py", line 166, in __init__
    hex = hex.replace('urn:', '').replace('uuid:', '')
AttributeError: 'asyncpg.pgproto.pgproto.UUID' object has no attribute 'replace'

PetrMixayloff avatar Jul 24 '20 12:07 PetrMixayloff

It doesn't need as_uuid=True because asyncpg already returns a UUID object as you see in the error message

wwwjfy avatar Aug 25 '20 16:08 wwwjfy

Hello. I'm now encountering a similar error.

My table state:

image

A static method that, according to Telegram ID, returns an instance of the User class:

image

I replaced this kind of statement with the following: image

This helped me, I hope it helps someone too

xwr-ron avatar Nov 12 '23 18:11 xwr-ron