-
Notifications
You must be signed in to change notification settings - Fork 197
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
SqlAlchemy dataclass support missing #737
Comments
Did you find a workaround for this? |
can you please post a minimal code to reproduce this? |
I have a bad hack only:
|
Thanks, but I mean a sample code to reproduce the issue. How do you define your models that this happens? |
here is a minimal code example to reproduce it. I was using litestar for that but you can easily replace it with FastAPI from litestar import Litestar
from sqladmin import ModelView
from sqladmin_litestar_plugin import SQLAdminPlugin
from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.asyncio import create_async_engine
from sqlalchemy.orm import declarative_base
from advanced_alchemy.base import UUIDAuditBase
from sqlalchemy import String
from sqlalchemy.orm import Mapped, mapped_column
import uvicorn
from typing import Any, ClassVar
from uuid import UUID
from datetime import datetime, timezone
from sqlalchemy import DateTime
from sqlalchemy.orm import (
DeclarativeBase,
Mapped,
mapped_column,
MappedAsDataclass
)
from uuid_utils.compat import uuid4
class Base(MappedAsDataclass, DeclarativeBase, kw_only=True):
type_annotation_map: ClassVar[dict[Any, Any]] = {
datetime: DateTime(timezone=True),
}
id: Mapped[UUID] = mapped_column(default=uuid4, primary_key=True)
"""Date/time of instance creation."""
created_at: Mapped[datetime] = mapped_column(
default=lambda: datetime.now(timezone.utc),
)
updated_at: Mapped[datetime] = mapped_column(
default=lambda: datetime.now(timezone.utc),
onupdate=lambda: datetime.now(timezone.utc),
)
engine = create_async_engine("postgresql+asyncpg://app:app@localhost:15432/laby_starter_dataset")
class User(Base):
"""User"""
__tablename__ = "user" # type: ignore[assignment]
__table_args__ = {"comment": "Users of laby"}
firstname: Mapped[str] = mapped_column(index=False, nullable=False)
lastname: Mapped[str] = mapped_column(index=False, nullable=False)
code: Mapped[str] = mapped_column(String(length=10), index=False, unique=True, nullable=False)
active: Mapped[bool] = mapped_column(index=False, nullable=False, default=True)
email_pro: Mapped[str | None] = mapped_column(String(length=255), index=False, nullable=False)
class Tier(Base):
"""Tier"""
__tablename__ = "tier" # type: ignore[assignment]
__table_args__ = {"comment": "Tiers"}
name: Mapped[str] = mapped_column(index=False, unique=True, nullable=False)
description: Mapped[str | None] = mapped_column(String(length=255), index=False, nullable=True)
active: Mapped[bool] = mapped_column(index=False, nullable=False, default=True)
activity: Mapped[str | None] = mapped_column(String(length=255),index=False, nullable=True)
class TierAdmin(ModelView, model=Tier):
name = "Tier"
name_plural = "Tiers"
column_list = [Tier.name, Tier.active, Tier.description]
column_labels = {Tier.name: "Name", Tier.active: "Status", Tier.description: "Description"}
icon = 'fa-solid fa-building'
column_details_exclude_list = [Tier.created_at, Tier.updated_at]
form_columns = [Tier.id, Tier.name, Tier.active, Tier.description]
class UserAdmin(ModelView, model=User):
name = "User"
name_plural = "Users"
column_list = [User.firstname, User.lastname]
column_labels = {User.firstname: "Firstname", User.lastname: "Lastname"}
icon = 'fa-solid fa-user'
column_details_exclude_list = [User.created_at, User.updated_at]
form_columns = [User.firstname, User.lastname, User.active, User.code, User.email_pro]
async def on_startup() -> None:
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all) # Create tables
admin = SQLAdminPlugin(views=[UserAdmin, TierAdmin], engine=engine)
app = Litestar(plugins=[admin], on_startup=[on_startup])
uvicorn.run(app) |
The problem is how we are creating a model instance without any arguments here and setting the column/relationship attributes on that object. It is tricky because when dealing with columns you can just pass kwargs to the object instantiation but for the relationships you have to load them beforehand. A workaround is to pass |
Checklist
master
.Describe the bug
If model mapped as dataclass (MappedAsDataclass), creating new record rises an error at sqladmin._queries:[194|206]
Steps to reproduce the bug
No response
Expected behavior
No response
Actual behavior
No response
Debugging material
No response
Environment
Additional context
No response
The text was updated successfully, but these errors were encountered: