pydantic-sqlalchemy
pydantic-sqlalchemy copied to clipboard
WIP: Add optional model name and only parameter to sqlalchemy_to_pydantic
I went ahead and added the new_model_name parameter to close #51 . Will add tests as well.
I also added an only field, that allows the reverse from exclude: only the mentioned fields will be included.
I am also thinking to add a class that does something similar. Basically, you would inherit from it set what model you want to use (similar to Django's Meta class for e.g. views) and which fields and in the constructor it calls the sqlalchemy_to_pydantic function (using the new class name as model name) and creates the schema.
For the test, I am not sure how to do it. I assume I could somehow get the cache map or whatever it is it's used for I tried to go through the create_model function but maybe it's easier if you tell me where you would like this functionality to be tested.
I am currently playing around with this
from pydantic import BaseModel
from pydantic.main import ModelMetaclass
from pydantic_sqlalchemy import sqlalchemy_to_pydantic
class MetaOptions:
def __init__(self, options):
self.model = getattr(options, "model", None)
self.exclude = getattr(options, "exclude", [])
class BaseMetaClass(ModelMetaclass):
def __new__(cls, name, bases, dct) -> None:
new_class = super().__new__(cls, name, bases, dct)
if bases == (BaseModel,):
return new_class
meta = MetaOptions(getattr(new_class, "Meta", None))
new_class = sqlalchemy_to_pydantic(
meta.model, exclude=meta.exclude, new_model_name=name
)
new_class._meta = meta
return new_class
class SQLAlchemyBaseModel(BaseModel, metaclass=BaseMetaClass):
pass
I don't have much experience with writing metaclasses but this seems to work.
You could use it like this:
class PyPostgresDB(SQLAlchemyBaseModel):
class Meta:
model = PostgresDB
class PyPostgresDBCreate(SQLAlchemyBaseModel):
class Meta:
model = PostgresDB
exclude = ["id"]
to create the schemas for a GET and POST request without running into the naming conflict and without needing to manually name the models.
@tiangolo Sorry for tagging you this shamelessly but is this something you would be interested in?
Also the above class approach has the disadvantage that you cant specify additional fields on the class (you need to use inheritance). I assume there is an easier way to drop the fields from sqlalchemy_to_pydantic to the base class in the __new__ function?
Thanks for the interest! And thanks for the patience with my reply. :sweat_smile:
I deprecated this library a while ago in favor of SQLModel which would solve all the same use cases in a much better way, and I'm directing all the effort in that direction, so sadly I wouldn't be able to take new features here (that would also need maintaining them).
Given that, I'll close this one, but thanks for the effort! :coffee: