EternalLeaner

Posts: 3 | Comments: 1

Recent Posts

Recent Comments

This is how it can be achieved.

from typing import Dict
from pydantic import BaseModel
from sqlalchemy import TypeDecorator
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.orm import Session
from sqlalchemy.orm import (
Mapped,
Session,
mapped_column,
)

# Pydantic
class UserMetadataSchema(BaseModel):
device_map: Dict[str, str] = {}

class UserdataMetadataJSONB(TypeDecorator):
impl = JSONB
cache_ok = True

def process_bind_param(self, value, dialect):
if value is not None:
return value.model_dump()
return value

def process_result_value(self, value, dialect):
if value is not None:
return UserMetadataSchema(**value)
return value

class User(Base):
__tablename__ = "user"
id: Mapped[int] = mapped_column(init=False, autoincrement=True, primary_key=True)
user_metadata: Mapped[UserMetadataSchema] = mapped_column(
UserdataMetadataJSONB, nullable=False
)

def main():
session: Session = None # fill with DB session
metadata = UserMetadataSchema(
device_map={"device": "samsung"},
)
# Create User with pydantic mapped column
user = User(
name="BirdWatcher",
user_metadata=UserMetadataSchema(**metadata.model_dump()),
)
session.add(user)
session.flush()
session.commit()

if __name__ == "__main__":
main()