Skip to content

Commit

Permalink
Bugfix: fixes for sqlalchemy (#85)
Browse files Browse the repository at this point in the history
* Added new setting to configure CROP and bump packages. Enhance doc and examples

* Fixes for sqlalchemy
  • Loading branch information
vsdudakov authored Dec 25, 2024
1 parent 9fe293f commit b85b8bc
Show file tree
Hide file tree
Showing 8 changed files with 1,455 additions and 1,302 deletions.
6 changes: 6 additions & 0 deletions docs/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ def read_cls_docstring(cls):

def get_versions():
return [
{
"version": "0.2.17",
"changes": [
"Fixes for fk sqlalchemy postgres. Convert str to int for them.",
],
},
{
"version": "0.2.16",
"changes": [
Expand Down
4 changes: 2 additions & 2 deletions docs/index.html

Large diffs are not rendered by default.

36 changes: 28 additions & 8 deletions fastadmin/models/orms/sqlalchemy.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import contextlib
from typing import Any
from uuid import UUID

from sqlalchemy import and_, func, inspect, or_, select, text
from sqlalchemy import BIGINT, Integer, and_, func, inspect, or_, select, text
from sqlalchemy.orm import selectinload

from fastadmin.models.base import InlineModelAdmin, ModelAdmin
Expand Down Expand Up @@ -261,21 +262,27 @@ def convert_sort_by(sort_by: str) -> str:
for field_with_condition, value in filters.items():
field = field_with_condition[0]
condition = field_with_condition[1]
model_field = getattr(self.model_cls, field)

if isinstance(model_field.expression.type, BIGINT | Integer):
with contextlib.suppress(ValueError):
value = int(value)

match condition:
case "lte":
q.append(getattr(self.model_cls, field) >= value)
q.append(model_field >= value)
case "gte":
q.append(getattr(self.model_cls, field) <= value)
q.append(model_field <= value)
case "lt":
q.append(getattr(self.model_cls, field) > value)
q.append(model_field > value)
case "gt":
q.append(getattr(self.model_cls, field) < value)
q.append(model_field < value)
case "exact":
q.append(getattr(self.model_cls, field) == value)
q.append(model_field == value)
case "contains":
q.append(getattr(self.model_cls, field).like(f"%{value}%"))
q.append(model_field.like(f"%{value}%"))
case "icontains":
q.append(getattr(self.model_cls, field).ilike(f"%{value}%"))
q.append(model_field.ilike(f"%{value}%"))
qs = qs.filter(and_(*q))

if search and self.search_fields:
Expand Down Expand Up @@ -313,13 +320,26 @@ async def orm_get_obj(self, id: UUID | int) -> Any | None:
async with sessionmaker() as session:
return await session.get(self.model_cls, id)

def _get_foreign_key_fields(self) -> list[str]:
"""Returns a list of foreign key fields for the model.
:return: List of foreign key field names.
"""
return [column.name for column in self.model_cls.__table__.columns if column.foreign_keys]

async def orm_save_obj(self, id: UUID | Any | None, payload: dict) -> Any:
"""This method is used to save orm/db model object.
:params id: an id of object.
:params payload: a dict of payload.
:return: An object.
"""
for fk_field_name in self._get_foreign_key_fields():
if fk_field_name in payload and isinstance(payload[fk_field_name], str):
with contextlib.suppress(ValueError):
# convert string to int for foreign key fields for postgresql alchemy
payload[fk_field_name] = int(payload[fk_field_name])

sessionmaker = self.get_sessionmaker()
async with sessionmaker() as session:
if id:
Expand Down
13 changes: 13 additions & 0 deletions fastadmin/static/assets/worker-MF2p-l5_.js

Large diffs are not rendered by default.

430 changes: 215 additions & 215 deletions fastadmin/static/index.min.js

Large diffs are not rendered by default.

Loading

0 comments on commit b85b8bc

Please sign in to comment.