Repository: litestar-org/litestar

Issue:
StaticFilesConfig and virtual directories
I'm trying to write a ``FileSystemProtocol`` to load files from the package data using [importlib_resources](https://importlib-resources.readthedocs.io/en/latest/using.html#). But because ``directories`` is defined as ``DirectoryPath``, pydantic checks if the given directories exist in the local filesystem. 

This is not generally true, especially in any kind of virtual filesystem (e.g. a zipped package). I think this condition should be relaxed to support virtual filesystems.

https://github.com/starlite-api/starlite/blob/9bb6dcd57c10a591377cf8e3a537e9292566d5b9/starlite/config/static_files.py#L32
Bug: BeforeAfter does not filter against the after value when using SQLAlchemyAsyncRepository
### Description

When trying to use the BeforeAfter filter using the SQLAlchemyAsyncRepository, i noticed my filtering was returning incorrect results, I looked in the code in SQLAlchemyAsyncRepository and notice the filtering function does not actually use the `after` value for the filtering

```
    def _filter_on_datetime_field(
        self, field_name: str, before: datetime | None, after: datetime | None, statement: SelectT
    ) -> SelectT:
        field = getattr(self.model_type, field_name)
        if before is not None:
            statement = statement.where(field < before)
        if after is not None:
            statement = statement.where(field > before).
        return statement
```

shouldn't the after condition be?

```
        if after is not None:
            statement = statement.where(field > after).
```


As a side note, can this filter's types be expanded to include ordinal types as well as inclusive values (e.g. >= and <=)

### URL to code causing the issue

### MCVE

```python
from datetime import datetime, timedelta

from litestar import Litestar, get
from litestar.contrib.sqlalchemy.dto import SQLAlchemyDTO
from litestar.contrib.repository.filters import BeforeAfter
from litestar.contrib.sqlalchemy.repository import SQLAlchemyAsyncRepository
from sqlalchemy.orm import DeclarativeBase, Mapped
from sqlalchemy.ext.asyncio import AsyncSession
from litestar.di import Provide


class User(DeclarativeBase):
    created_at: Mapped[datetime]


UserDTO = SQLAlchemyDTO[User]


class UserRepository(SQLAlchemyAsyncRepository[UserDTO]):
    model_type = User


@get("/users", dto=UserDTO)
def create_user(user_repo: UserRepository) -> User:
    now = datetime.now()
    return user_repo.list(
        BeforeAfter("created_at", now - timedelta(hours=3), now - timedelta(hours=1))


async def provide_repo(db_session: AsyncSession) -> UserRepository:
    return UserRepository(session=db_session)

app = Litestar(route_handlers=[create_user], dependencies={"user_repo": Provide(provide_repo)})
```


### Steps to reproduce


### Screenshots


### Logs

### Litestar Version

2.0.0alpha7

### Platform

- [ ] Linux
- [X] Mac
- [ ] Windows
- [ ] Other (Please specify in the description above)


Discussion:
I agree. Do you want to submit a PR?
Thanks for reporting this.  I'll take a look today.

Resolving patch:
diff --git a/litestar/contrib/sqlalchemy/repository.py b/litestar/contrib/sqlalchemy/repository.py
--- a/litestar/contrib/sqlalchemy/repository.py
+++ b/litestar/contrib/sqlalchemy/repository.py
@@ -536,7 +536,7 @@ def _filter_on_datetime_field(
         if before is not None:
             statement = statement.where(field < before)
         if after is not None:
-            statement = statement.where(field > before)
+            statement = statement.where(field > after)
         return statement
 
     def _filter_select_by_kwargs(self, statement: SelectT, **kwargs: Any) -> SelectT:
@@ -1026,7 +1026,7 @@ def _filter_on_datetime_field(
         if before is not None:
             statement = statement.where(field < before)
         if after is not None:
-            statement = statement.where(field > before)
+            statement = statement.where(field > after)
         return statement
 
     def _filter_select_by_kwargs(self, statement: SelectT, **kwargs: Any) -> SelectT:


Test patch:
diff --git a/tests/contrib/sqlalchemy/repository/conftest.py b/tests/contrib/sqlalchemy/repository/conftest.py
--- a/tests/contrib/sqlalchemy/repository/conftest.py
+++ b/tests/contrib/sqlalchemy/repository/conftest.py
@@ -59,15 +59,15 @@ def fx_raw_authors() -> list[dict[str, Any]]:
             "id": UUID("97108ac1-ffcb-411d-8b1e-d9183399f63b"),
             "name": "Agatha Christie",
             "dob": "1890-09-15",
-            "created": "0001-01-01T00:00:00",
-            "updated": "0001-01-01T00:00:00",
+            "created": "2023-05-01T00:00:00",
+            "updated": "2023-05-11T00:00:00",
         },
         {
             "id": "5ef29f3c-3560-4d15-ba6b-a2e5c721e4d2",
             "name": "Leo Tolstoy",
             "dob": "1828-09-09",
-            "created": "0001-01-01T00:00:00",
-            "updated": "0001-01-01T00:00:00",
+            "created": "2023-03-01T00:00:00",
+            "updated": "2023-05-15T00:00:00",
         },
     ]
 
diff --git a/tests/contrib/sqlalchemy/repository/sqlalchemy_async_tests.py b/tests/contrib/sqlalchemy/repository/sqlalchemy_async_tests.py
--- a/tests/contrib/sqlalchemy/repository/sqlalchemy_async_tests.py
+++ b/tests/contrib/sqlalchemy/repository/sqlalchemy_async_tests.py
@@ -12,6 +12,7 @@
 )
 
 from litestar.contrib.repository.exceptions import RepositoryError
+from litestar.contrib.repository.filters import BeforeAfter, CollectionFilter, OrderBy, SearchFilter
 from litestar.contrib.sqlalchemy import base
 from tests.contrib.sqlalchemy.models import (
     Author,
@@ -55,17 +56,17 @@ def test_filter_by_kwargs_with_incorrect_attribute_name(author_repo: AuthorAsync
     """Test SQLALchemy filter by kwargs with invalid column name.
 
     Args:
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorAsyncRepository): The author mock repository
     """
     with pytest.raises(RepositoryError):
         author_repo.filter_collection_by_kwargs(author_repo.statement, whoops="silly me")
 
 
 async def test_repo_count_method(author_repo: AuthorAsyncRepository, store_repo: StoreAsyncRepository) -> None:
-    """Test SQLALchemy count with asyncpg.
+    """Test SQLALchemy count.
 
     Args:
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorAsyncRepository): The author mock repository
     """
     assert await author_repo.count() == 2
     assert await store_repo.count() == 2
@@ -81,7 +82,7 @@ async def test_repo_list_and_count_method(
 
     Args:
         raw_authors (list[dict[str, Any]]): list of authors pre-seeded into the mock repository
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorAsyncRepository): The author mock repository
         raw_stores (list[dict[str, Any]]): list of stores pre-seeded into the mock repository
         store_repo (StoreRepository): The store mock repository
     """
@@ -103,7 +104,7 @@ async def test_repo_list_and_count_method_empty(book_repo: BookAsyncRepository)
 
     Args:
         raw_authors (list[dict[str, Any]]): list of authors pre-seeded into the mock repository
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorAsyncRepository): The author mock repository
     """
 
     collection, count = await book_repo.list_and_count()
@@ -118,11 +119,11 @@ async def test_repo_list_method(
     raw_stores: list[dict[str, Any]],
     store_repo: StoreAsyncRepository,
 ) -> None:
-    """Test SQLALchemy list with asyncpg.
+    """Test SQLALchemy list.
 
     Args:
         raw_authors (list[dict[str, Any]]): list of authors pre-seeded into the mock repository
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorAsyncRepository): The author mock repository
         raw_stores (list[dict[str, Any]]): list of stores pre-seeded into the mock repository
         store_repo (StoreRepository): The store mock repository
     """
@@ -143,11 +144,11 @@ async def test_repo_add_method(
     raw_stores: list[dict[str, Any]],
     store_repo: StoreAsyncRepository,
 ) -> None:
-    """Test SQLALchemy Add with asyncpg.
+    """Test SQLALchemy Add.
 
     Args:
         raw_authors (list[dict[str, Any]]): list of authors pre-seeded into the mock repository
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorAsyncRepository): The author mock repository
         raw_stores (list[dict[str, Any]]): list of stores pre-seeded into the mock repository
         store_repo (StoreRepository): The store mock repository
     """
@@ -172,11 +173,11 @@ async def test_repo_add_method(
 
 
 async def test_repo_add_many_method(raw_authors: list[dict[str, Any]], author_repo: AuthorAsyncRepository) -> None:
-    """Test SQLALchemy Add Many with asyncpg.
+    """Test SQLALchemy Add Many.
 
     Args:
         raw_authors (list[dict[str, Any]]): list of authors pre-seeded into the mock repository
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorAsyncRepository): The author mock repository
     """
     exp_count = len(raw_authors) + 2
     objs = await author_repo.add_many(
@@ -192,10 +193,10 @@ async def test_repo_add_many_method(raw_authors: list[dict[str, Any]], author_re
 
 
 async def test_repo_update_many_method(author_repo: AuthorAsyncRepository) -> None:
-    """Test SQLALchemy Update Many with asyncpg.
+    """Test SQLALchemy Update Many.
 
     Args:
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorAsyncRepository): The author mock repository
     """
     objs = await author_repo.list()
     for idx, obj in enumerate(objs):
@@ -206,20 +207,20 @@ async def test_repo_update_many_method(author_repo: AuthorAsyncRepository) -> No
 
 
 async def test_repo_exists_method(author_repo: AuthorAsyncRepository) -> None:
-    """Test SQLALchemy exists with asyncpg.
+    """Test SQLALchemy exists.
 
     Args:
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorAsyncRepository): The author mock repository
     """
     exists = await author_repo.exists(id=UUID("97108ac1-ffcb-411d-8b1e-d9183399f63b"))
     assert exists
 
 
 async def test_repo_update_method(author_repo: AuthorAsyncRepository) -> None:
-    """Test SQLALchemy Update with asyncpg.
+    """Test SQLALchemy Update.
 
     Args:
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorAsyncRepository): The author mock repository
     """
     obj = await author_repo.get(UUID("97108ac1-ffcb-411d-8b1e-d9183399f63b"))
     obj.name = "Updated Name"
@@ -228,20 +229,20 @@ async def test_repo_update_method(author_repo: AuthorAsyncRepository) -> None:
 
 
 async def test_repo_delete_method(author_repo: AuthorAsyncRepository) -> None:
-    """Test SQLALchemy delete with asyncpg.
+    """Test SQLALchemy delete.
 
     Args:
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorAsyncRepository): The author mock repository
     """
     obj = await author_repo.delete(UUID("97108ac1-ffcb-411d-8b1e-d9183399f63b"))
     assert obj.id == UUID("97108ac1-ffcb-411d-8b1e-d9183399f63b")
 
 
 async def test_repo_delete_many_method(author_repo: AuthorAsyncRepository) -> None:
-    """Test SQLALchemy delete many with asyncpg.
+    """Test SQLALchemy delete many.
 
     Args:
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorAsyncRepository): The author mock repository
     """
     data_to_insert = []
     for chunk in range(0, 1000):
@@ -262,20 +263,20 @@ async def test_repo_delete_many_method(author_repo: AuthorAsyncRepository) -> No
 
 
 async def test_repo_get_method(author_repo: AuthorAsyncRepository) -> None:
-    """Test SQLALchemy Get with asyncpg.
+    """Test SQLALchemy Get.
 
     Args:
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorAsyncRepository): The author mock repository
     """
     obj = await author_repo.get(UUID("97108ac1-ffcb-411d-8b1e-d9183399f63b"))
     assert obj.name == "Agatha Christie"
 
 
 async def test_repo_get_one_or_none_method(author_repo: AuthorAsyncRepository) -> None:
-    """Test SQLALchemy Get One with asyncpg.
+    """Test SQLALchemy Get One.
 
     Args:
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorAsyncRepository): The author mock repository
     """
     obj = await author_repo.get_one_or_none(id=UUID("97108ac1-ffcb-411d-8b1e-d9183399f63b"))
     assert obj is not None
@@ -285,10 +286,10 @@ async def test_repo_get_one_or_none_method(author_repo: AuthorAsyncRepository) -
 
 
 async def test_repo_get_one_method(author_repo: AuthorAsyncRepository) -> None:
-    """Test SQLALchemy Get One with asyncpg.
+    """Test SQLALchemy Get One.
 
     Args:
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorAsyncRepository): The author mock repository
     """
     obj = await author_repo.get_one(id=UUID("97108ac1-ffcb-411d-8b1e-d9183399f63b"))
     assert obj is not None
@@ -298,10 +299,10 @@ async def test_repo_get_one_method(author_repo: AuthorAsyncRepository) -> None:
 
 
 async def test_repo_get_or_create_method(author_repo: AuthorAsyncRepository) -> None:
-    """Test SQLALchemy Get or create with asyncpg.
+    """Test SQLALchemy Get or create.
 
     Args:
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorAsyncRepository): The author mock repository
     """
     existing_obj, existing_created = await author_repo.get_or_create(name="Agatha Christie")
     assert existing_obj.id == UUID("97108ac1-ffcb-411d-8b1e-d9183399f63b")
@@ -316,7 +317,7 @@ async def test_repo_get_or_create_match_filter(author_repo: AuthorAsyncRepositor
     """Test SQLALchemy Get or create with a match filter
 
     Args:
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorAsyncRepository): The author mock repository
     """
     now = datetime.now()
     existing_obj, existing_created = await author_repo.get_or_create(
@@ -328,10 +329,10 @@ async def test_repo_get_or_create_match_filter(author_repo: AuthorAsyncRepositor
 
 
 async def test_repo_upsert_method(author_repo: AuthorAsyncRepository) -> None:
-    """Test SQLALchemy upsert with asyncpg.
+    """Test SQLALchemy upsert.
 
     Args:
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorAsyncRepository): The author mock repository
     """
     existing_obj = await author_repo.get_one(name="Agatha Christie")
     existing_obj.name = "Agatha C."
@@ -347,3 +348,74 @@ async def test_repo_upsert_method(author_repo: AuthorAsyncRepository) -> None:
     upsert2_insert_obj = await author_repo.upsert(Author(id=uuid4(), name="Another Author"))
     assert upsert2_insert_obj.id is not None
     assert upsert2_insert_obj.name == "Another Author"
+
+
+async def test_repo_filter_before_after(author_repo: AuthorAsyncRepository) -> None:
+    """Test SQLALchemy before after filter.
+
+    Args:
+        author_repo (AuthorAsyncRepository): The author mock repository
+    """
+    before_filter = BeforeAfter(
+        field_name="created", before=datetime.strptime("2023-05-01T00:00:00", "%Y-%m-%dT%H:%M:%S"), after=None
+    )
+    existing_obj = await author_repo.list(before_filter)
+    assert existing_obj[0].name == "Leo Tolstoy"
+
+    after_filter = BeforeAfter(
+        field_name="created", after=datetime.strptime("2023-03-01T00:00:00", "%Y-%m-%dT%H:%M:%S"), before=None
+    )
+    existing_obj = await author_repo.list(after_filter)
+    assert existing_obj[0].name == "Agatha Christie"
+
+
+async def test_repo_filter_search(author_repo: AuthorAsyncRepository) -> None:
+    """Test SQLALchemy search filter.
+
+    Args:
+        author_repo (AuthorAsyncRepository): The author mock repository
+    """
+
+    existing_obj = await author_repo.list(SearchFilter(field_name="name", value="gath", ignore_case=False))
+    assert existing_obj[0].name == "Agatha Christie"
+    existing_obj = await author_repo.list(SearchFilter(field_name="name", value="GATH", ignore_case=False))
+    # sqlite & mysql are case insensitive by default with a `LIKE`
+    dialect = author_repo.session.bind.dialect.name if author_repo.session.bind else "default"
+    if dialect in {"sqlite", "mysql"}:
+        expected_objs = 1
+    else:
+        expected_objs = 0
+    assert len(existing_obj) == expected_objs
+    existing_obj = await author_repo.list(SearchFilter(field_name="name", value="GATH", ignore_case=True))
+    assert existing_obj[0].name == "Agatha Christie"
+
+
+async def test_repo_filter_order_by(author_repo: AuthorAsyncRepository) -> None:
+    """Test SQLALchemy order by filter.
+
+    Args:
+        author_repo (AuthorAsyncRepository): The author mock repository
+    """
+
+    existing_obj = await author_repo.list(OrderBy(field_name="created", sort_order="desc"))
+    assert existing_obj[0].name == "Agatha Christie"
+    existing_obj = await author_repo.list(OrderBy(field_name="created", sort_order="asc"))
+    assert existing_obj[0].name == "Leo Tolstoy"
+
+
+async def test_repo_filter_collection(author_repo: AuthorAsyncRepository) -> None:
+    """Test SQLALchemy collection filter.
+
+    Args:
+        author_repo (AuthorAsyncRepository): The author mock repository
+    """
+
+    existing_obj = await author_repo.list(
+        CollectionFilter(field_name="id", values=[UUID("97108ac1-ffcb-411d-8b1e-d9183399f63b")])
+    )
+    assert existing_obj[0].name == "Agatha Christie"
+
+    existing_obj = await author_repo.list(
+        CollectionFilter(field_name="id", values=[UUID("5ef29f3c-3560-4d15-ba6b-a2e5c721e4d2")])
+    )
+    assert existing_obj[0].name == "Leo Tolstoy"
diff --git a/tests/contrib/sqlalchemy/repository/sqlalchemy_sync_tests.py b/tests/contrib/sqlalchemy/repository/sqlalchemy_sync_tests.py
--- a/tests/contrib/sqlalchemy/repository/sqlalchemy_sync_tests.py
+++ b/tests/contrib/sqlalchemy/repository/sqlalchemy_sync_tests.py
@@ -9,6 +9,7 @@
 from sqlalchemy import Engine, insert
 
 from litestar.contrib.repository.exceptions import RepositoryError
+from litestar.contrib.repository.filters import BeforeAfter, CollectionFilter, OrderBy, SearchFilter
 from litestar.contrib.sqlalchemy import base
 from tests.contrib.sqlalchemy.models import (
     Author,
@@ -55,17 +56,17 @@ def test_filter_by_kwargs_with_incorrect_attribute_name(author_repo: AuthorSyncR
     """Test SQLALchemy filter by kwargs with invalid column name.
 
     Args:
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorSyncRepository): The author mock repository
     """
     with pytest.raises(RepositoryError):
         author_repo.filter_collection_by_kwargs(author_repo.statement, whoops="silly me")
 
 
 def test_repo_count_method(author_repo: AuthorSyncRepository, store_repo: StoreSyncRepository) -> None:
-    """Test SQLALchemy count with asyncpg.
+    """Test SQLALchemy count.
 
     Args:
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorSyncRepository): The author mock repository
     """
     assert author_repo.count() == 2
     assert store_repo.count() == 2
@@ -81,7 +82,7 @@ def test_repo_list_and_count_method(
 
     Args:
         raw_authors (list[dict[str, Any]]): list of authors pre-seeded into the mock repository
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorSyncRepository): The author mock repository
         raw_stores (list[dict[str, Any]]): list of stores pre-seeded into the mock repository
         store_repo (StoreRepository): The store mock repository
     """
@@ -103,7 +104,7 @@ def test_repo_list_and_count_method_empty(book_repo: BookSyncRepository) -> None
 
     Args:
         raw_authors (list[dict[str, Any]]): list of authors pre-seeded into the mock repository
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorSyncRepository): The author mock repository
     """
 
     collection, count = book_repo.list_and_count()
@@ -118,11 +119,11 @@ def test_repo_list_method(
     raw_stores: list[dict[str, Any]],
     store_repo: StoreSyncRepository,
 ) -> None:
-    """Test SQLALchemy list with asyncpg.
+    """Test SQLALchemy list.
 
     Args:
         raw_authors (list[dict[str, Any]]): list of authors pre-seeded into the mock repository
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorSyncRepository): The author mock repository
         raw_stores (list[dict[str, Any]]): list of stores pre-seeded into the mock repository
         store_repo (StoreRepository): The store mock repository
     """
@@ -143,11 +144,11 @@ def test_repo_add_method(
     raw_stores: list[dict[str, Any]],
     store_repo: StoreSyncRepository,
 ) -> None:
-    """Test SQLALchemy Add with asyncpg.
+    """Test SQLALchemy Add.
 
     Args:
         raw_authors (list[dict[str, Any]]): list of authors pre-seeded into the mock repository
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorSyncRepository): The author mock repository
         raw_stores (list[dict[str, Any]]): list of stores pre-seeded into the mock repository
         store_repo (StoreRepository): The store mock repository
     """
@@ -172,11 +173,11 @@ def test_repo_add_method(
 
 
 def test_repo_add_many_method(raw_authors: list[dict[str, Any]], author_repo: AuthorSyncRepository) -> None:
-    """Test SQLALchemy Add Many with asyncpg.
+    """Test SQLALchemy Add Many.
 
     Args:
         raw_authors (list[dict[str, Any]]): list of authors pre-seeded into the mock repository
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorSyncRepository): The author mock repository
     """
     exp_count = len(raw_authors) + 2
     objs = author_repo.add_many([Author(name="Testing 2", dob=datetime.now()), Author(name="Cody", dob=datetime.now())])
@@ -190,10 +191,10 @@ def test_repo_add_many_method(raw_authors: list[dict[str, Any]], author_repo: Au
 
 
 def test_repo_update_many_method(author_repo: AuthorSyncRepository) -> None:
-    """Test SQLALchemy Update Many with asyncpg.
+    """Test SQLALchemy Update Many.
 
     Args:
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorSyncRepository): The author mock repository
     """
     objs = author_repo.list()
     for idx, obj in enumerate(objs):
@@ -204,20 +205,20 @@ def test_repo_update_many_method(author_repo: AuthorSyncRepository) -> None:
 
 
 def test_repo_exists_method(author_repo: AuthorSyncRepository) -> None:
-    """Test SQLALchemy exists with asyncpg.
+    """Test SQLALchemy exists.
 
     Args:
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorSyncRepository): The author mock repository
     """
     exists = author_repo.exists(id=UUID("97108ac1-ffcb-411d-8b1e-d9183399f63b"))
     assert exists
 
 
 def test_repo_update_method(author_repo: AuthorSyncRepository) -> None:
-    """Test SQLALchemy Update with asyncpg.
+    """Test SQLALchemy Update.
 
     Args:
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorSyncRepository): The author mock repository
     """
     obj = author_repo.get(UUID("97108ac1-ffcb-411d-8b1e-d9183399f63b"))
     obj.name = "Updated Name"
@@ -226,20 +227,20 @@ def test_repo_update_method(author_repo: AuthorSyncRepository) -> None:
 
 
 def test_repo_delete_method(author_repo: AuthorSyncRepository) -> None:
-    """Test SQLALchemy delete with asyncpg.
+    """Test SQLALchemy delete.
 
     Args:
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorSyncRepository): The author mock repository
     """
     obj = author_repo.delete(UUID("97108ac1-ffcb-411d-8b1e-d9183399f63b"))
     assert obj.id == UUID("97108ac1-ffcb-411d-8b1e-d9183399f63b")
 
 
 def test_repo_delete_many_method(author_repo: AuthorSyncRepository) -> None:
-    """Test SQLALchemy delete many with asyncpg.
+    """Test SQLALchemy delete many.
 
     Args:
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorSyncRepository): The author mock repository
     """
     data_to_insert = []
     for chunk in range(0, 1000):
@@ -260,20 +261,20 @@ def test_repo_delete_many_method(author_repo: AuthorSyncRepository) -> None:
 
 
 def test_repo_get_method(author_repo: AuthorSyncRepository) -> None:
-    """Test SQLALchemy Get with asyncpg.
+    """Test SQLALchemy Get.
 
     Args:
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorSyncRepository): The author mock repository
     """
     obj = author_repo.get(UUID("97108ac1-ffcb-411d-8b1e-d9183399f63b"))
     assert obj.name == "Agatha Christie"
 
 
 def test_repo_get_one_or_none_method(author_repo: AuthorSyncRepository) -> None:
-    """Test SQLALchemy Get One with asyncpg.
+    """Test SQLALchemy Get One.
 
     Args:
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorSyncRepository): The author mock repository
     """
     obj = author_repo.get_one_or_none(id=UUID("97108ac1-ffcb-411d-8b1e-d9183399f63b"))
     assert obj is not None
@@ -283,10 +284,10 @@ def test_repo_get_one_or_none_method(author_repo: AuthorSyncRepository) -> None:
 
 
 def test_repo_get_one_method(author_repo: AuthorSyncRepository) -> None:
-    """Test SQLALchemy Get One with asyncpg.
+    """Test SQLALchemy Get One.
 
     Args:
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorSyncRepository): The author mock repository
     """
     obj = author_repo.get_one(id=UUID("97108ac1-ffcb-411d-8b1e-d9183399f63b"))
     assert obj is not None
@@ -296,10 +297,10 @@ def test_repo_get_one_method(author_repo: AuthorSyncRepository) -> None:
 
 
 def test_repo_get_or_create_method(author_repo: AuthorSyncRepository) -> None:
-    """Test SQLALchemy Get or create with asyncpg.
+    """Test SQLALchemy Get or create.
 
     Args:
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorSyncRepository): The author mock repository
     """
     existing_obj, existing_created = author_repo.get_or_create(name="Agatha Christie")
     assert existing_obj.id == UUID("97108ac1-ffcb-411d-8b1e-d9183399f63b")
@@ -314,7 +315,7 @@ def test_repo_get_or_create_match_filter(author_repo: AuthorSyncRepository) -> N
     """Test SQLALchemy Get or create with a match filter
 
     Args:
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorSyncRepository): The author mock repository
     """
     now = datetime.now()
     existing_obj, existing_created = author_repo.get_or_create(match_fields="name", name="Agatha Christie", dob=now)
@@ -324,10 +325,10 @@ def test_repo_get_or_create_match_filter(author_repo: AuthorSyncRepository) -> N
 
 
 def test_repo_upsert_method(author_repo: AuthorSyncRepository) -> None:
-    """Test SQLALchemy upsert with asyncpg.
+    """Test SQLALchemy upsert.
 
     Args:
-        author_repo (AuthorRepository): The author mock repository
+        author_repo (AuthorSyncRepository): The author mock repository
     """
     existing_obj = author_repo.get_one(name="Agatha Christie")
     existing_obj.name = "Agatha C."
@@ -343,3 +344,74 @@ def test_repo_upsert_method(author_repo: AuthorSyncRepository) -> None:
     upsert2_insert_obj = author_repo.upsert(Author(id=uuid4(), name="Another Author"))
     assert upsert2_insert_obj.id is not None
     assert upsert2_insert_obj.name == "Another Author"
+
+
+def test_repo_filter_before_after(author_repo: AuthorSyncRepository) -> None:
+    """Test SQLALchemy upsert.
+
+    Args:
+        author_repo (AuthorSyncRepository): The author mock repository
+    """
+    before_filter = BeforeAfter(
+        field_name="created", before=datetime.strptime("2023-05-01T00:00:00", "%Y-%m-%dT%H:%M:%S"), after=None
+    )
+    existing_obj = author_repo.list(before_filter)
+    assert existing_obj[0].name == "Leo Tolstoy"
+
+    after_filter = BeforeAfter(
+        field_name="created", after=datetime.strptime("2023-03-01T00:00:00", "%Y-%m-%dT%H:%M:%S"), before=None
+    )
+    existing_obj = author_repo.list(after_filter)
+    assert existing_obj[0].name == "Agatha Christie"
+
+
+def test_repo_filter_search(author_repo: AuthorSyncRepository) -> None:
+    """Test SQLALchemy upsert.
+
+    Args:
+        author_repo (AuthorSyncRepository): The author mock repository
+    """
+
+    existing_obj = author_repo.list(SearchFilter(field_name="name", value="gath", ignore_case=False))
+    assert existing_obj[0].name == "Agatha Christie"
+    existing_obj = author_repo.list(SearchFilter(field_name="name", value="GATH", ignore_case=False))
+    # sqlite & mysql are case insensitive by default with a `LIKE`
+    dialect = author_repo.session.bind.dialect.name if author_repo.session.bind else "default"
+    if dialect in {"sqlite", "mysql"}:
+        expected_objs = 1
+    else:
+        expected_objs = 0
+    assert len(existing_obj) == expected_objs
+    existing_obj = author_repo.list(SearchFilter(field_name="name", value="GATH", ignore_case=True))
+    assert existing_obj[0].name == "Agatha Christie"
+
+
+def test_repo_filter_order_by(author_repo: AuthorSyncRepository) -> None:
+    """Test SQLALchemy upsert.
+
+    Args:
+        author_repo (AuthorSyncRepository): The author mock repository
+    """
+
+    existing_obj = author_repo.list(OrderBy(field_name="created", sort_order="desc"))
+    assert existing_obj[0].name == "Agatha Christie"
+    existing_obj = author_repo.list(OrderBy(field_name="created", sort_order="asc"))
+    assert existing_obj[0].name == "Leo Tolstoy"
+
+
+def test_repo_filter_collection(author_repo: AuthorSyncRepository) -> None:
+    """Test SQLALchemy upsert.
+
+    Args:
+        author_repo (AuthorSyncRepository): The author mock repository
+    """
+
+    existing_obj = author_repo.list(
+        CollectionFilter(field_name="id", values=[UUID("97108ac1-ffcb-411d-8b1e-d9183399f63b")])
+    )
+    assert existing_obj[0].name == "Agatha Christie"
+
+    existing_obj = author_repo.list(
+        CollectionFilter(field_name="id", values=[UUID("5ef29f3c-3560-4d15-ba6b-a2e5c721e4d2")])
+    )
+    assert existing_obj[0].name == "Leo Tolstoy"
diff --git a/tests/contrib/sqlalchemy/repository/test_sqlalchemy_aiosqlite.py b/tests/contrib/sqlalchemy/repository/test_sqlalchemy_aiosqlite.py
--- a/tests/contrib/sqlalchemy/repository/test_sqlalchemy_aiosqlite.py
+++ b/tests/contrib/sqlalchemy/repository/test_sqlalchemy_aiosqlite.py
@@ -296,3 +296,43 @@ async def test_repo_upsert_method(author_repo: AuthorAsyncRepository) -> None:
         author_repo (AuthorRepository): The author mock repository
     """
     await st.test_repo_upsert_method(author_repo=author_repo)
+
+
+@pytest.mark.sqlalchemy_aiosqlite
+async def test_repo_filter_before_after(author_repo: AuthorAsyncRepository) -> None:
+    """Test SQLALchemy BeforeAfter filter.
+
+    Args:
+        author_repo (AuthorRepository): The author mock repository
+    """
+    await st.test_repo_filter_before_after(author_repo=author_repo)
+
+
+@pytest.mark.sqlalchemy_aiosqlite
+async def test_repo_filter_search(author_repo: AuthorAsyncRepository) -> None:
+    """Test SQLALchemy Search filter.
+
+    Args:
+        author_repo (AuthorRepository): The author mock repository
+    """
+    await st.test_repo_filter_search(author_repo=author_repo)
+
+
+@pytest.mark.sqlalchemy_aiosqlite
+async def test_repo_filter_order_by(author_repo: AuthorAsyncRepository) -> None:
+    """Test SQLALchemy Order By filter.
+
+    Args:
+        author_repo (AuthorRepository): The author mock repository
+    """
+    await st.test_repo_filter_order_by(author_repo=author_repo)
+
+
+@pytest.mark.sqlalchemy_aiosqlite
+async def test_repo_filter_collection(author_repo: AuthorAsyncRepository) -> None:
+    """Test SQLALchemy Collection filter.
+
+    Args:
+        author_repo (AuthorRepository): The author mock repository
+    """
+    await st.test_repo_filter_collection(author_repo=author_repo)
diff --git a/tests/contrib/sqlalchemy/repository/test_sqlalchemy_asyncmy.py b/tests/contrib/sqlalchemy/repository/test_sqlalchemy_asyncmy.py
--- a/tests/contrib/sqlalchemy/repository/test_sqlalchemy_asyncmy.py
+++ b/tests/contrib/sqlalchemy/repository/test_sqlalchemy_asyncmy.py
@@ -307,3 +307,43 @@ async def test_repo_upsert_method(author_repo: AuthorAsyncRepository) -> None:
         author_repo (AuthorRepository): The author mock repository
     """
     await st.test_repo_upsert_method(author_repo=author_repo)
+
+
+@pytest.mark.sqlalchemy_asyncmy
+async def test_repo_filter_before_after(author_repo: AuthorAsyncRepository) -> None:
+    """Test SQLALchemy BeforeAfter filter.
+
+    Args:
+        author_repo (AuthorRepository): The author mock repository
+    """
+    await st.test_repo_filter_before_after(author_repo=author_repo)
+
+
+@pytest.mark.sqlalchemy_asyncmy
+async def test_repo_filter_search(author_repo: AuthorAsyncRepository) -> None:
+    """Test SQLALchemy Search filter.
+
+    Args:
+        author_repo (AuthorRepository): The author mock repository
+    """
+    await st.test_repo_filter_search(author_repo=author_repo)
+
+
+@pytest.mark.sqlalchemy_asyncmy
+async def test_repo_filter_order_by(author_repo: AuthorAsyncRepository) -> None:
+    """Test SQLALchemy Order By filter.
+
+    Args:
+        author_repo (AuthorRepository): The author mock repository
+    """
+    await st.test_repo_filter_order_by(author_repo=author_repo)
+
+
+@pytest.mark.sqlalchemy_asyncmy
+async def test_repo_filter_collection(author_repo: AuthorAsyncRepository) -> None:
+    """Test SQLALchemy Collection filter.
+
+    Args:
+        author_repo (AuthorRepository): The author mock repository
+    """
+    await st.test_repo_filter_collection(author_repo=author_repo)
diff --git a/tests/contrib/sqlalchemy/repository/test_sqlalchemy_asyncpg.py b/tests/contrib/sqlalchemy/repository/test_sqlalchemy_asyncpg.py
--- a/tests/contrib/sqlalchemy/repository/test_sqlalchemy_asyncpg.py
+++ b/tests/contrib/sqlalchemy/repository/test_sqlalchemy_asyncpg.py
@@ -307,3 +307,43 @@ async def test_repo_upsert_method(author_repo: AuthorAsyncRepository) -> None:
         author_repo (AuthorRepository): The author mock repository
     """
     await st.test_repo_upsert_method(author_repo=author_repo)
+
+
+@pytest.mark.sqlalchemy_asyncpg
+async def test_repo_filter_before_after(author_repo: AuthorAsyncRepository) -> None:
+    """Test SQLALchemy BeforeAfter filter.
+
+    Args:
+        author_repo (AuthorRepository): The author mock repository
+    """
+    await st.test_repo_filter_before_after(author_repo=author_repo)
+
+
+@pytest.mark.sqlalchemy_asyncpg
+async def test_repo_filter_search(author_repo: AuthorAsyncRepository) -> None:
+    """Test SQLALchemy Search filter.
+
+    Args:
+        author_repo (AuthorRepository): The author mock repository
+    """
+    await st.test_repo_filter_search(author_repo=author_repo)
+
+
+@pytest.mark.sqlalchemy_asyncpg
+async def test_repo_filter_order_by(author_repo: AuthorAsyncRepository) -> None:
+    """Test SQLALchemy Order By filter.
+
+    Args:
+        author_repo (AuthorRepository): The author mock repository
+    """
+    await st.test_repo_filter_order_by(author_repo=author_repo)
+
+
+@pytest.mark.sqlalchemy_asyncpg
+async def test_repo_filter_collection(author_repo: AuthorAsyncRepository) -> None:
+    """Test SQLALchemy Collection filter.
+
+    Args:
+        author_repo (AuthorRepository): The author mock repository
+    """
+    await st.test_repo_filter_collection(author_repo=author_repo)
diff --git a/tests/contrib/sqlalchemy/repository/test_sqlalchemy_oracledb.py b/tests/contrib/sqlalchemy/repository/test_sqlalchemy_oracledb.py
--- a/tests/contrib/sqlalchemy/repository/test_sqlalchemy_oracledb.py
+++ b/tests/contrib/sqlalchemy/repository/test_sqlalchemy_oracledb.py
@@ -304,3 +304,43 @@ def test_repo_upsert_method(author_repo: AuthorSyncRepository) -> None:
         author_repo (AuthorRepository): The author mock repository
     """
     st.test_repo_upsert_method(author_repo=author_repo)
+
+
+@pytest.mark.sqlalchemy_oracledb
+def test_repo_filter_before_after(author_repo: AuthorSyncRepository) -> None:
+    """Test SQLALchemy BeforeAfter filter.
+
+    Args:
+        author_repo (AuthorRepository): The author mock repository
+    """
+    st.test_repo_filter_before_after(author_repo=author_repo)
+
+
+@pytest.mark.sqlalchemy_oracledb
+def test_repo_filter_search(author_repo: AuthorSyncRepository) -> None:
+    """Test SQLALchemy Search filter.
+
+    Args:
+        author_repo (AuthorRepository): The author mock repository
+    """
+    st.test_repo_filter_search(author_repo=author_repo)
+
+
+@pytest.mark.sqlalchemy_oracledb
+def test_repo_filter_order_by(author_repo: AuthorSyncRepository) -> None:
+    """Test SQLALchemy Order By filter.
+
+    Args:
+        author_repo (AuthorRepository): The author mock repository
+    """
+    st.test_repo_filter_order_by(author_repo=author_repo)
+
+
+@pytest.mark.sqlalchemy_oracledb
+def test_repo_filter_collection(author_repo: AuthorSyncRepository) -> None:
+    """Test SQLALchemy Collection filter.
+
+    Args:
+        author_repo (AuthorRepository): The author mock repository
+    """
+    st.test_repo_filter_collection(author_repo=author_repo)
diff --git a/tests/contrib/sqlalchemy/repository/test_sqlalchemy_psycopg_async.py b/tests/contrib/sqlalchemy/repository/test_sqlalchemy_psycopg_async.py
--- a/tests/contrib/sqlalchemy/repository/test_sqlalchemy_psycopg_async.py
+++ b/tests/contrib/sqlalchemy/repository/test_sqlalchemy_psycopg_async.py
@@ -307,3 +307,43 @@ async def test_repo_upsert_method(author_repo: AuthorAsyncRepository) -> None:
         author_repo (AuthorRepository): The author mock repository
     """
     await st.test_repo_upsert_method(author_repo=author_repo)
+
+
+@pytest.mark.sqlalchemy_psycopg_async
+async def test_repo_filter_before_after(author_repo: AuthorAsyncRepository) -> None:
+    """Test SQLALchemy BeforeAfter filter.
+
+    Args:
+        author_repo (AuthorRepository): The author mock repository
+    """
+    await st.test_repo_filter_before_after(author_repo=author_repo)
+
+
+@pytest.mark.sqlalchemy_psycopg_async
+async def test_repo_filter_search(author_repo: AuthorAsyncRepository) -> None:
+    """Test SQLALchemy Search filter.
+
+    Args:
+        author_repo (AuthorRepository): The author mock repository
+    """
+    await st.test_repo_filter_search(author_repo=author_repo)
+
+
+@pytest.mark.sqlalchemy_psycopg_async
+async def test_repo_filter_order_by(author_repo: AuthorAsyncRepository) -> None:
+    """Test SQLALchemy Order By filter.
+
+    Args:
+        author_repo (AuthorRepository): The author mock repository
+    """
+    await st.test_repo_filter_order_by(author_repo=author_repo)
+
+
+@pytest.mark.sqlalchemy_psycopg_async
+async def test_repo_filter_collection(author_repo: AuthorAsyncRepository) -> None:
+    """Test SQLALchemy Collection filter.
+
+    Args:
+        author_repo (AuthorRepository): The author mock repository
+    """
+    await st.test_repo_filter_collection(author_repo=author_repo)
diff --git a/tests/contrib/sqlalchemy/repository/test_sqlalchemy_psycopg_sync.py b/tests/contrib/sqlalchemy/repository/test_sqlalchemy_psycopg_sync.py
--- a/tests/contrib/sqlalchemy/repository/test_sqlalchemy_psycopg_sync.py
+++ b/tests/contrib/sqlalchemy/repository/test_sqlalchemy_psycopg_sync.py
@@ -302,3 +302,43 @@ def test_repo_upsert_method(author_repo: AuthorSyncRepository) -> None:
         author_repo (AuthorRepository): The author mock repository
     """
     st.test_repo_upsert_method(author_repo=author_repo)
+
+
+@pytest.mark.sqlalchemy_psycopg_sync
+def test_repo_filter_before_after(author_repo: AuthorSyncRepository) -> None:
+    """Test SQLALchemy BeforeAfter filter.
+
+    Args:
+        author_repo (AuthorRepository): The author mock repository
+    """
+    st.test_repo_filter_before_after(author_repo=author_repo)
+
+
+@pytest.mark.sqlalchemy_psycopg_sync
+def test_repo_filter_search(author_repo: AuthorSyncRepository) -> None:
+    """Test SQLALchemy Search filter.
+
+    Args:
+        author_repo (AuthorRepository): The author mock repository
+    """
+    st.test_repo_filter_search(author_repo=author_repo)
+
+
+@pytest.mark.sqlalchemy_psycopg_sync
+def test_repo_filter_order_by(author_repo: AuthorSyncRepository) -> None:
+    """Test SQLALchemy Order By filter.
+
+    Args:
+        author_repo (AuthorRepository): The author mock repository
+    """
+    st.test_repo_filter_order_by(author_repo=author_repo)
+
+
+@pytest.mark.sqlalchemy_psycopg_sync
+def test_repo_filter_collection(author_repo: AuthorSyncRepository) -> None:
+    """Test SQLALchemy Collection filter.
+
+    Args:
+        author_repo (AuthorRepository): The author mock repository
+    """
+    st.test_repo_filter_collection(author_repo=author_repo)
diff --git a/tests/contrib/sqlalchemy/repository/test_sqlalchemy_sqlite.py b/tests/contrib/sqlalchemy/repository/test_sqlalchemy_sqlite.py
--- a/tests/contrib/sqlalchemy/repository/test_sqlalchemy_sqlite.py
+++ b/tests/contrib/sqlalchemy/repository/test_sqlalchemy_sqlite.py
@@ -301,3 +301,43 @@ def test_repo_upsert_method(author_repo: AuthorSyncRepository) -> None:
         author_repo (AuthorRepository): The author mock repository
     """
     st.test_repo_upsert_method(author_repo=author_repo)
+
+
+@pytest.mark.sqlalchemy_sqlite
+def test_repo_filter_before_after(author_repo: AuthorSyncRepository) -> None:
+    """Test SQLALchemy BeforeAfter filter.
+
+    Args:
+        author_repo (AuthorRepository): The author mock repository
+    """
+    st.test_repo_filter_before_after(author_repo=author_repo)
+
+
+@pytest.mark.sqlalchemy_sqlite
+def test_repo_filter_search(author_repo: AuthorSyncRepository) -> None:
+    """Test SQLALchemy Search filter.
+
+    Args:
+        author_repo (AuthorRepository): The author mock repository
+    """
+    st.test_repo_filter_search(author_repo=author_repo)
+
+
+@pytest.mark.sqlalchemy_sqlite
+def test_repo_filter_order_by(author_repo: AuthorSyncRepository) -> None:
+    """Test SQLALchemy Order By filter.
+
+    Args:
+        author_repo (AuthorRepository): The author mock repository
+    """
+    st.test_repo_filter_order_by(author_repo=author_repo)
+
+
+@pytest.mark.sqlalchemy_sqlite
+def test_repo_filter_collection(author_repo: AuthorSyncRepository) -> None:
+    """Test SQLALchemy Collection filter.
+
+    Args:
+        author_repo (AuthorRepository): The author mock repository
+    """
+    st.test_repo_filter_collection(author_repo=author_repo)