mirror of
https://github.com/d3vyce/fastapi-toolsets.git
synced 2026-03-01 17:00:48 +01:00
fix: cast to String non-text columns for crud search
This commit is contained in:
@@ -129,11 +129,12 @@ def build_search_filters(
|
||||
else:
|
||||
column = field
|
||||
|
||||
# Build the filter
|
||||
# Build the filter (cast to String for non-text columns)
|
||||
column_as_string = column.cast(String)
|
||||
if config.case_sensitive:
|
||||
filters.append(column.like(f"%{query}%"))
|
||||
filters.append(column_as_string.like(f"%{query}%"))
|
||||
else:
|
||||
filters.append(column.ilike(f"%{query}%"))
|
||||
filters.append(column_as_string.ilike(f"%{query}%"))
|
||||
|
||||
if not filters:
|
||||
return [], []
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
"""Tests for CRUD search functionality."""
|
||||
|
||||
import pytest
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
import uuid
|
||||
|
||||
from fastapi_toolsets.crud import SearchConfig, get_searchable_fields
|
||||
import pytest
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy import String
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
|
||||
from fastapi_toolsets.crud import CrudFactory, SearchConfig, get_searchable_fields
|
||||
|
||||
from .conftest import (
|
||||
Base,
|
||||
Role,
|
||||
RoleCreate,
|
||||
RoleCrud,
|
||||
@@ -272,6 +278,41 @@ class TestPaginateSearch:
|
||||
usernames = [u.username for u in result["data"]]
|
||||
assert usernames == ["alice", "bob", "charlie"]
|
||||
|
||||
@pytest.mark.anyio
|
||||
async def test_search_non_string_column(self, db_session: AsyncSession):
|
||||
"""Search on non-string columns (e.g., UUID) works via cast."""
|
||||
|
||||
class Account(Base):
|
||||
__tablename__ = "accounts"
|
||||
id: Mapped[uuid.UUID] = mapped_column(primary_key=True, default=uuid.uuid4)
|
||||
name: Mapped[str] = mapped_column(String(100))
|
||||
|
||||
class AccountCreate(BaseModel):
|
||||
id: uuid.UUID | None = None
|
||||
name: str
|
||||
|
||||
AccountCrud = CrudFactory(Account)
|
||||
|
||||
# Create table for this test
|
||||
async with db_session.get_bind().begin() as conn:
|
||||
await conn.run_sync(Base.metadata.create_all)
|
||||
|
||||
account_id = uuid.UUID("12345678-1234-5678-1234-567812345678")
|
||||
await AccountCrud.create(
|
||||
db_session, AccountCreate(id=account_id, name="Test Account")
|
||||
)
|
||||
await AccountCrud.create(db_session, AccountCreate(name="Other Account"))
|
||||
|
||||
# Search by UUID (partial match)
|
||||
result = await AccountCrud.paginate(
|
||||
db_session,
|
||||
search="12345678",
|
||||
search_fields=[Account.id, Account.name],
|
||||
)
|
||||
|
||||
assert result["pagination"]["total_count"] == 1
|
||||
assert result["data"][0].id == account_id
|
||||
|
||||
|
||||
class TestSearchConfig:
|
||||
"""Tests for SearchConfig options."""
|
||||
|
||||
Reference in New Issue
Block a user