Skip to content

Commit

Permalink
raw but working version of getting nested users
Browse files Browse the repository at this point in the history
User model has City model, City model has Country model,
all pydantic models generated by my metaclass
  • Loading branch information
mrtedn21 committed Sep 14, 2023
1 parent aa4eadf commit f3044cb
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 8 deletions.
23 changes: 19 additions & 4 deletions database.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ def __new__(cls, name, bases, fields):
field_name for field_name in dir(origin_model)
if not field_name.startswith('_')
and field_name not in alchemy_fields
and not cls.is_secondary_relation(origin_model, field_name)
and not cls.is_property_secondary_relation(origin_model, field_name)
and not cls.is_property_foreign_key(origin_model, field_name)
]

defined_fields = fields['fields']
Expand All @@ -74,9 +75,10 @@ def __new__(cls, name, bases, fields):
result_fields.update({
field_name: (fields[field_name], ...)
for field_name in defined_fields
if field_name in origin_model_field_names and
if field_name in origin_model_field_names
and fields.get(field_name)
# if alchemy field hasn't 'type' property, it means the field is relation
not hasattr(getattr(origin_model, field_name), 'type')
and not hasattr(getattr(origin_model, field_name), 'type')
})

result_model = create_model(
Expand All @@ -88,7 +90,7 @@ def __new__(cls, name, bases, fields):
return result_model

@staticmethod
def is_secondary_relation(model, attribute_name):
def is_property_secondary_relation(model, attribute_name):
"""Sqlalchemy in its models force define one relation in two models.
What means. For example will take model order and model product.
Every order may have one product. In database, in sql when we create
Expand All @@ -114,6 +116,19 @@ def is_secondary_relation(model, attribute_name):
else:
return False

@staticmethod
def is_property_foreign_key(model, attribute_name):
attribute = getattr(model, attribute_name)
try:
foreign_keys = attribute.foreign_keys
except AttributeError:
return False

if foreign_keys:
return True
else:
return False


class UserOrm(Base):
__tablename__ = 'users'
Expand Down
15 changes: 11 additions & 4 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,18 @@ class UserCreateModel(UserOrm, metaclass=SqlAlchemyToPydantic):
@register_route('/users/', ('get', ))
async def get_users() -> list[UserGetModel]:
async with db.create_session() as session:
sql_query = select(UserOrm)
sql_query = select(
UserOrm, CityOrm, CountryOrm
).select_from(UserOrm).join(CityOrm).join(CountryOrm)
result = await session.execute(sql_query)
users = result.scalars().all()
user_dicts = list(map(get_dict_from_orm_object, users))
return json.dumps(user_dicts)

users = []
for user in result.fetchall():
user_pydantic = UserGetModel.model_validate(user[0])
user_dict = user_pydantic.model_dump()
user_dict['birth_date'] = str(user_dict['birth_date'])
users.append(user_dict)
return json.dumps(users)


@register_route('/users/', ('post', ))
Expand Down

0 comments on commit f3044cb

Please sign in to comment.