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


Discussion:
I agree. Do you want to submit a PR?

Resolving patch:
diff --git a/litestar/contrib/sqlalchemy/base.py b/litestar/contrib/sqlalchemy/base.py
--- a/litestar/contrib/sqlalchemy/base.py
+++ b/litestar/contrib/sqlalchemy/base.py
@@ -19,7 +19,7 @@
     registry,
 )
 
-from .types import GUID, JSON, BigIntIdentity
+from .types import GUID, BigIntIdentity, JsonB
 
 if TYPE_CHECKING:
     from sqlalchemy.sql import FromClause
@@ -151,7 +151,7 @@ def create_registry() -> registry:
             EmailStr: String,
             AnyUrl: String,
             AnyHttpUrl: String,
-            dict: JSON,
+            dict: JsonB,
             datetime: DateTime,
             date: Date,
         },
diff --git a/litestar/contrib/sqlalchemy/types.py b/litestar/contrib/sqlalchemy/types.py
--- a/litestar/contrib/sqlalchemy/types.py
+++ b/litestar/contrib/sqlalchemy/types.py
@@ -9,14 +9,14 @@
 from sqlalchemy.dialects.oracle import RAW as ORA_RAW
 from sqlalchemy.dialects.postgresql import JSONB as PG_JSONB
 from sqlalchemy.dialects.postgresql import UUID as PG_UUID
-from sqlalchemy.types import BINARY, CHAR, BigInteger, Integer, SchemaType, TypeDecorator
+from sqlalchemy.types import BINARY, CHAR, BigInteger, Integer, SchemaType, TypeDecorator, TypeEngine
 from sqlalchemy.types import JSON as _JSON
 
+from litestar.serialization import decode_json, encode_json
+
 if TYPE_CHECKING:
     from sqlalchemy.engine import Dialect
 
-BigIntIdentity = BigInteger().with_variant(Integer, "sqlite")
-
 
 class GUID(TypeDecorator):
     """Platform-independent GUID type.
@@ -81,16 +81,14 @@ def to_uuid(value: Any) -> uuid.UUID | None:
         return cast("uuid.UUID | None", value)
 
 
-class JSON(TypeDecorator, SchemaType):  # type: ignore
-    """Platform-independent JSON type.
-
-    Uses JSONB type for postgres, BLOB for Oracle, otherwise uses the generic JSON data type.
+class ORA_JSONB(TypeDecorator, SchemaType):  # type: ignore  # noqa: N801
+    """Oracle Binary JSON type.
 
-    JSON = _JSON().with_variant(PG_JSONB, "postgresql").with_variant(ORA_BLOB, "oracle")
+    JsonB = _JSON().with_variant(PG_JSONB, "postgresql").with_variant(ORA_JSONB, "oracle")
 
     """
 
-    impl = _JSON
+    impl = ORA_BLOB
     cache_ok = True
 
     @property
@@ -102,12 +100,21 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:
         self.name = kwargs.pop("name", None)
         self.oracle_strict = kwargs.pop("oracle_strict", True)
 
-    def load_dialect_impl(self, dialect: Dialect) -> Any:
-        if dialect.name == "postgresql":
-            return dialect.type_descriptor(PG_JSONB())  # type: ignore
-        if dialect.name == "oracle":
-            return dialect.type_descriptor(ORA_BLOB())
-        return dialect.type_descriptor(_JSON())
+    def coerce_compared_value(self, op: Any, value: Any) -> Any:
+        return self.impl.coerce_compared_value(op=op, value=value)  # type: ignore
+
+    def load_dialect_impl(self, dialect: Dialect) -> TypeEngine[Any]:
+        return dialect.type_descriptor(ORA_BLOB())
+
+    def process_bind_param(self, value: Any, dialect: Dialect) -> Any | None:
+        if value is None:
+            return value
+        return encode_json(value)
+
+    def process_result_value(self, value: bytes | None, dialect: Dialect) -> Any | None:
+        if value is None:
+            return value
+        return decode_json(value)
 
     def _should_create_constraint(self, compiler: Any, **kw: Any) -> bool:
         return bool(compiler.dialect.name == "oracle")
@@ -136,3 +143,7 @@ def _set_table(self, column: Any, table: Any) -> None:
             _type_bound=True,
         )
         table.append_constraint(e)
+
+
+BigIntIdentity = BigInteger().with_variant(Integer, "sqlite")
+JsonB = _JSON().with_variant(PG_JSONB, "postgresql").with_variant(ORA_JSONB, "oracle")


Test patch:
diff --git a/tests/contrib/sqlalchemy/models_bigint.py b/tests/contrib/sqlalchemy/models_bigint.py
--- a/tests/contrib/sqlalchemy/models_bigint.py
+++ b/tests/contrib/sqlalchemy/models_bigint.py
@@ -32,6 +32,19 @@ class BigIntEventLog(BigIntAuditBase):
     payload: Mapped[dict] = mapped_column(default=lambda: {})  # pyright: ignore
 
 
+class BigIntRule(BigIntAuditBase):
+    """The rule domain object."""
+
+    name: Mapped[str] = mapped_column(String(length=250))  # pyright: ignore
+    config: Mapped[dict] = mapped_column(default=lambda: {})  # pyright: ignore
+
+
+class RuleAsyncRepository(SQLAlchemyAsyncRepository[BigIntRule]):
+    """Rule repository."""
+
+    model_type = BigIntRule
+
+
 class AuthorAsyncRepository(SQLAlchemyAsyncRepository[BigIntAuthor]):
     """Author repository."""
 
@@ -66,3 +79,9 @@ class EventLogSyncRepository(SQLAlchemySyncRepository[BigIntEventLog]):
     """Event log repository."""
 
     model_type = BigIntEventLog
+
+
+class RuleSyncRepository(SQLAlchemySyncRepository[BigIntRule]):
+    """Rule repository."""
+
+    model_type = BigIntRule
diff --git a/tests/contrib/sqlalchemy/models_uuid.py b/tests/contrib/sqlalchemy/models_uuid.py
--- a/tests/contrib/sqlalchemy/models_uuid.py
+++ b/tests/contrib/sqlalchemy/models_uuid.py
@@ -33,6 +33,19 @@ class UUIDEventLog(UUIDAuditBase):
     payload: Mapped[dict] = mapped_column(default={})  # pyright: ignore
 
 
+class UUIDRule(UUIDAuditBase):
+    """The rule domain object."""
+
+    name: Mapped[str] = mapped_column(String(length=250))  # pyright: ignore
+    config: Mapped[dict] = mapped_column(default=lambda: {})  # pyright: ignore
+
+
+class RuleAsyncRepository(SQLAlchemyAsyncRepository[UUIDRule]):
+    """Rule repository."""
+
+    model_type = UUIDRule
+
+
 class AuthorAsyncRepository(SQLAlchemyAsyncRepository[UUIDAuthor]):
     """Author repository."""
 
@@ -67,3 +80,9 @@ class EventLogSyncRepository(SQLAlchemySyncRepository[UUIDEventLog]):
     """Event log repository."""
 
     model_type = UUIDEventLog
+
+
+class RuleSyncRepository(SQLAlchemySyncRepository[UUIDRule]):
+    """Rule repository."""
+
+    model_type = UUIDRule
diff --git a/tests/contrib/sqlalchemy/repository/aiosqlite/test_sqlalchemy_aiosqlite_bigint.py b/tests/contrib/sqlalchemy/repository/aiosqlite/test_sqlalchemy_aiosqlite_bigint.py
--- a/tests/contrib/sqlalchemy/repository/aiosqlite/test_sqlalchemy_aiosqlite_bigint.py
+++ b/tests/contrib/sqlalchemy/repository/aiosqlite/test_sqlalchemy_aiosqlite_bigint.py
@@ -13,7 +13,11 @@
     create_async_engine,
 )
 
-from tests.contrib.sqlalchemy.models_bigint import AuthorAsyncRepository, BookAsyncRepository
+from tests.contrib.sqlalchemy.models_bigint import (
+    AuthorAsyncRepository,
+    BookAsyncRepository,
+    RuleAsyncRepository,
+)
 from tests.contrib.sqlalchemy.repository import sqlalchemy_async_bigint_tests as st
 
 pytestmark = pytest.mark.sqlalchemy_aiosqlite
@@ -41,10 +45,13 @@ async def fx_engine(tmp_path: Path) -> AsyncGenerator[AsyncEngine, None]:
     name="session",
 )
 async def fx_session(
-    engine: AsyncEngine, raw_authors_bigint: list[dict[str, Any]], raw_books_bigint: list[dict[str, Any]]
+    engine: AsyncEngine,
+    raw_authors_bigint: list[dict[str, Any]],
+    raw_books_bigint: list[dict[str, Any]],
+    raw_rules_bigint: list[dict[str, Any]],
 ) -> AsyncGenerator[AsyncSession, None]:
     session = async_sessionmaker(bind=engine)()
-    await st.seed_db(engine, raw_authors_bigint, raw_books_bigint)
+    await st.seed_db(engine, raw_authors_bigint, raw_books_bigint, raw_rules_bigint)
     try:
         yield session
     finally:
@@ -62,6 +69,11 @@ def fx_book_repo(session: AsyncSession) -> BookAsyncRepository:
     return BookAsyncRepository(session=session)
 
 
+@pytest.fixture(name="rule_repo")
+def fx_rule_repo(session: AsyncSession) -> RuleAsyncRepository:
+    return RuleAsyncRepository(session=session)
+
+
 def test_filter_by_kwargs_with_incorrect_attribute_name(author_repo: AuthorAsyncRepository) -> None:
     """Test SQLALchemy filter by kwargs with invalid column name.
 
@@ -270,3 +282,16 @@ async def test_repo_filter_collection(author_repo: AuthorAsyncRepository) -> Non
         author_repo (AuthorRepository): The author mock repository
     """
     await st.test_repo_filter_collection(author_repo=author_repo)
+
+
+async def test_repo_json_methods(
+    raw_rules_bigint: list[dict[str, Any]],
+    rule_repo: RuleAsyncRepository,
+) -> None:
+    """Test SQLALchemy Collection filter.
+
+    Args:
+        raw_rules_bigint (list[dict[str, Any]]): list of rules pre-seeded into the mock repository
+        rule_repo (AuthorAsyncRepository): The rules mock repository
+    """
+    await st.test_repo_json_methods(raw_rules_bigint=raw_rules_bigint, rule_repo=rule_repo)
diff --git a/tests/contrib/sqlalchemy/repository/aiosqlite/test_sqlalchemy_aiosqlite_uuid.py b/tests/contrib/sqlalchemy/repository/aiosqlite/test_sqlalchemy_aiosqlite_uuid.py
--- a/tests/contrib/sqlalchemy/repository/aiosqlite/test_sqlalchemy_aiosqlite_uuid.py
+++ b/tests/contrib/sqlalchemy/repository/aiosqlite/test_sqlalchemy_aiosqlite_uuid.py
@@ -13,7 +13,11 @@
     create_async_engine,
 )
 
-from tests.contrib.sqlalchemy.models_uuid import AuthorAsyncRepository, BookAsyncRepository
+from tests.contrib.sqlalchemy.models_uuid import (
+    AuthorAsyncRepository,
+    BookAsyncRepository,
+    RuleAsyncRepository,
+)
 from tests.contrib.sqlalchemy.repository import sqlalchemy_async_uuid_tests as st
 
 pytestmark = pytest.mark.sqlalchemy_aiosqlite
@@ -41,10 +45,13 @@ async def fx_engine(tmp_path: Path) -> AsyncGenerator[AsyncEngine, None]:
     name="session",
 )
 async def fx_session(
-    engine: AsyncEngine, raw_authors_uuid: list[dict[str, Any]], raw_books_uuid: list[dict[str, Any]]
+    engine: AsyncEngine,
+    raw_authors_uuid: list[dict[str, Any]],
+    raw_books_uuid: list[dict[str, Any]],
+    raw_rules_uuid: list[dict[str, Any]],
 ) -> AsyncGenerator[AsyncSession, None]:
     session = async_sessionmaker(bind=engine)()
-    await st.seed_db(engine, raw_authors_uuid, raw_books_uuid)
+    await st.seed_db(engine, raw_authors_uuid, raw_books_uuid, raw_rules_uuid)
     try:
         yield session
     finally:
@@ -62,6 +69,11 @@ def fx_book_repo(session: AsyncSession) -> BookAsyncRepository:
     return BookAsyncRepository(session=session)
 
 
+@pytest.fixture(name="rule_repo")
+def fx_rule_repo(session: AsyncSession) -> RuleAsyncRepository:
+    return RuleAsyncRepository(session=session)
+
+
 def test_filter_by_kwargs_with_incorrect_attribute_name(author_repo: AuthorAsyncRepository) -> None:
     """Test SQLALchemy filter by kwargs with invalid column name.
 
@@ -276,3 +288,16 @@ async def test_repo_filter_collection(author_repo: AuthorAsyncRepository) -> Non
         author_repo (AuthorRepository): The author mock repository
     """
     await st.test_repo_filter_collection(author_repo=author_repo)
+
+
+async def test_repo_json_methods(
+    raw_rules_uuid: list[dict[str, Any]],
+    rule_repo: RuleAsyncRepository,
+) -> None:
+    """Test SQLALchemy Collection filter.
+
+    Args:
+        raw_rules_uuid (list[dict[str, Any]]): list of rules pre-seeded into the mock repository
+        rules_repo (AuthorAsyncRepository): The rules mock repository
+    """
+    await st.test_repo_json_methods(raw_rules_uuid=raw_rules_uuid, rule_repo=rule_repo)
diff --git a/tests/contrib/sqlalchemy/repository/asyncmy/test_sqlalchemy_asyncmy_bigint.py b/tests/contrib/sqlalchemy/repository/asyncmy/test_sqlalchemy_asyncmy_bigint.py
--- a/tests/contrib/sqlalchemy/repository/asyncmy/test_sqlalchemy_asyncmy_bigint.py
+++ b/tests/contrib/sqlalchemy/repository/asyncmy/test_sqlalchemy_asyncmy_bigint.py
@@ -14,7 +14,7 @@
     create_async_engine,
 )
 
-from tests.contrib.sqlalchemy.models_bigint import AuthorAsyncRepository, BookAsyncRepository
+from tests.contrib.sqlalchemy.models_bigint import AuthorAsyncRepository, BookAsyncRepository, RuleAsyncRepository
 from tests.contrib.sqlalchemy.repository import sqlalchemy_async_bigint_tests as st
 
 pytestmark = [
@@ -52,10 +52,13 @@ async def fx_engine(docker_ip: str) -> AsyncEngine:
 
 @pytest.fixture(name="session")
 async def fx_session(
-    engine: AsyncEngine, raw_authors_bigint: list[dict[str, Any]], raw_books_bigint: list[dict[str, Any]]
+    engine: AsyncEngine,
+    raw_authors_bigint: list[dict[str, Any]],
+    raw_books_bigint: list[dict[str, Any]],
+    raw_rules_bigint: list[dict[str, Any]],
 ) -> AsyncGenerator[AsyncSession, None]:
     session = async_sessionmaker(bind=engine)()
-    await st.seed_db(engine, raw_authors_bigint, raw_books_bigint)
+    await st.seed_db(engine, raw_authors_bigint, raw_books_bigint, raw_rules_bigint)
     try:
         yield session
     finally:
@@ -73,6 +76,11 @@ def fx_book_repo(session: AsyncSession) -> BookAsyncRepository:
     return BookAsyncRepository(session=session)
 
 
+@pytest.fixture(name="rule_repo")
+def fx_rule_repo(session: AsyncSession) -> RuleAsyncRepository:
+    return RuleAsyncRepository(session=session)
+
+
 def test_filter_by_kwargs_with_incorrect_attribute_name(author_repo: AuthorAsyncRepository) -> None:
     """Test SQLALchemy filter by kwargs with invalid column name.
 
@@ -279,3 +287,16 @@ async def test_repo_filter_collection(author_repo: AuthorAsyncRepository) -> Non
         author_repo (AuthorRepository): The author mock repository
     """
     await st.test_repo_filter_collection(author_repo=author_repo)
+
+
+async def test_repo_json_methods(
+    raw_rules_bigint: list[dict[str, Any]],
+    rule_repo: RuleAsyncRepository,
+) -> None:
+    """Test SQLALchemy Collection filter.
+
+    Args:
+        raw_rules_bigint (list[dict[str, Any]]): list of rules pre-seeded into the mock repository
+        rule_repo (AuthorAsyncRepository): The rules mock repository
+    """
+    await st.test_repo_json_methods(raw_rules_bigint=raw_rules_bigint, rule_repo=rule_repo)
diff --git a/tests/contrib/sqlalchemy/repository/asyncmy/test_sqlalchemy_asyncmy_uuid.py b/tests/contrib/sqlalchemy/repository/asyncmy/test_sqlalchemy_asyncmy_uuid.py
--- a/tests/contrib/sqlalchemy/repository/asyncmy/test_sqlalchemy_asyncmy_uuid.py
+++ b/tests/contrib/sqlalchemy/repository/asyncmy/test_sqlalchemy_asyncmy_uuid.py
@@ -17,6 +17,7 @@
 from tests.contrib.sqlalchemy.models_uuid import (
     AuthorAsyncRepository,
     BookAsyncRepository,
+    RuleAsyncRepository,
 )
 from tests.contrib.sqlalchemy.repository import sqlalchemy_async_uuid_tests as st
 
@@ -55,10 +56,13 @@ async def fx_engine(docker_ip: str) -> AsyncEngine:
 
 @pytest.fixture(name="session")
 async def fx_session(
-    engine: AsyncEngine, raw_authors_uuid: list[dict[str, Any]], raw_books_uuid: list[dict[str, Any]]
+    engine: AsyncEngine,
+    raw_authors_uuid: list[dict[str, Any]],
+    raw_books_uuid: list[dict[str, Any]],
+    raw_rules_uuid: list[dict[str, Any]],
 ) -> AsyncGenerator[AsyncSession, None]:
     session = async_sessionmaker(bind=engine)()
-    await st.seed_db(engine, raw_authors_uuid, raw_books_uuid)
+    await st.seed_db(engine, raw_authors_uuid, raw_books_uuid, raw_rules_uuid)
     try:
         yield session
     finally:
@@ -76,6 +80,11 @@ def fx_book_repo(session: AsyncSession) -> BookAsyncRepository:
     return BookAsyncRepository(session=session)
 
 
+@pytest.fixture(name="rule_repo")
+def fx_rule_repo(session: AsyncSession) -> RuleAsyncRepository:
+    return RuleAsyncRepository(session=session)
+
+
 def test_filter_by_kwargs_with_incorrect_attribute_name(author_repo: AuthorAsyncRepository) -> None:
     """Test SQLALchemy filter by kwargs with invalid column name.
 
@@ -280,3 +289,16 @@ async def test_repo_filter_collection(author_repo: AuthorAsyncRepository) -> Non
         author_repo (AuthorRepository): The author mock repository
     """
     await st.test_repo_filter_collection(author_repo=author_repo)
+
+
+async def test_repo_json_methods(
+    raw_rules_uuid: list[dict[str, Any]],
+    rule_repo: RuleAsyncRepository,
+) -> None:
+    """Test SQLALchemy Collection filter.
+
+    Args:
+        raw_rules_uuid (list[dict[str, Any]]): list of rules pre-seeded into the mock repository
+        rules_repo (AuthorAsyncRepository): The rules mock repository
+    """
+    await st.test_repo_json_methods(raw_rules_uuid=raw_rules_uuid, rule_repo=rule_repo)
diff --git a/tests/contrib/sqlalchemy/repository/asyncpg/test_sqlalchemy_asyncpg_bigint.py b/tests/contrib/sqlalchemy/repository/asyncpg/test_sqlalchemy_asyncpg_bigint.py
--- a/tests/contrib/sqlalchemy/repository/asyncpg/test_sqlalchemy_asyncpg_bigint.py
+++ b/tests/contrib/sqlalchemy/repository/asyncpg/test_sqlalchemy_asyncpg_bigint.py
@@ -17,6 +17,7 @@
 from tests.contrib.sqlalchemy.models_bigint import (
     AuthorAsyncRepository,
     BookAsyncRepository,
+    RuleAsyncRepository,
 )
 from tests.contrib.sqlalchemy.repository import sqlalchemy_async_bigint_tests as st
 
@@ -57,10 +58,13 @@ async def fx_engine(docker_ip: str) -> AsyncEngine:
     name="session",
 )
 async def fx_session(
-    engine: AsyncEngine, raw_authors_bigint: list[dict[str, Any]], raw_books_uuid: list[dict[str, Any]]
+    engine: AsyncEngine,
+    raw_authors_bigint: list[dict[str, Any]],
+    raw_books_uuid: list[dict[str, Any]],
+    raw_rules_bigint: list[dict[str, Any]],
 ) -> AsyncGenerator[AsyncSession, None]:
     session = async_sessionmaker(bind=engine)()
-    await st.seed_db(engine, raw_authors_bigint, raw_books_uuid)
+    await st.seed_db(engine, raw_authors_bigint, raw_books_uuid, raw_rules_bigint)
     try:
         yield session
     finally:
@@ -78,6 +82,11 @@ def fx_book_repo(session: AsyncSession) -> BookAsyncRepository:
     return BookAsyncRepository(session=session)
 
 
+@pytest.fixture(name="rule_repo")
+def fx_rule_repo(session: AsyncSession) -> RuleAsyncRepository:
+    return RuleAsyncRepository(session=session)
+
+
 def test_filter_by_kwargs_with_incorrect_attribute_name(author_repo: AuthorAsyncRepository) -> None:
     """Test SQLALchemy filter by kwargs with invalid column name.
 
@@ -284,3 +293,16 @@ async def test_repo_filter_collection(author_repo: AuthorAsyncRepository) -> Non
         author_repo (AuthorRepository): The author mock repository
     """
     await st.test_repo_filter_collection(author_repo=author_repo)
+
+
+async def test_repo_json_methods(
+    raw_rules_bigint: list[dict[str, Any]],
+    rule_repo: RuleAsyncRepository,
+) -> None:
+    """Test SQLALchemy Collection filter.
+
+    Args:
+        raw_rules_bigint (list[dict[str, Any]]): list of rules pre-seeded into the mock repository
+        rule_repo (AuthorAsyncRepository): The rules mock repository
+    """
+    await st.test_repo_json_methods(raw_rules_bigint=raw_rules_bigint, rule_repo=rule_repo)
diff --git a/tests/contrib/sqlalchemy/repository/asyncpg/test_sqlalchemy_asyncpg_uuid.py b/tests/contrib/sqlalchemy/repository/asyncpg/test_sqlalchemy_asyncpg_uuid.py
--- a/tests/contrib/sqlalchemy/repository/asyncpg/test_sqlalchemy_asyncpg_uuid.py
+++ b/tests/contrib/sqlalchemy/repository/asyncpg/test_sqlalchemy_asyncpg_uuid.py
@@ -17,6 +17,7 @@
 from tests.contrib.sqlalchemy.models_uuid import (
     AuthorAsyncRepository,
     BookAsyncRepository,
+    RuleAsyncRepository,
 )
 from tests.contrib.sqlalchemy.repository import sqlalchemy_async_uuid_tests as st
 
@@ -60,9 +61,10 @@ async def fx_session(
     engine: AsyncEngine,
     raw_authors_uuid: list[dict[str, Any]],
     raw_books_uuid: list[dict[str, Any]],
+    raw_rules_uuid: list[dict[str, Any]],
 ) -> AsyncGenerator[AsyncSession, None]:
     session = async_sessionmaker(bind=engine)()
-    await st.seed_db(engine, raw_authors_uuid, raw_books_uuid)
+    await st.seed_db(engine, raw_authors_uuid, raw_books_uuid, raw_rules_uuid)
     try:
         yield session
     finally:
@@ -80,6 +82,11 @@ def fx_book_repo(session: AsyncSession) -> BookAsyncRepository:
     return BookAsyncRepository(session=session)
 
 
+@pytest.fixture(name="rule_repo")
+def fx_rule_repo(session: AsyncSession) -> RuleAsyncRepository:
+    return RuleAsyncRepository(session=session)
+
+
 def test_filter_by_kwargs_with_incorrect_attribute_name(author_repo: AuthorAsyncRepository) -> None:
     """Test SQLALchemy filter by kwargs with invalid column name.
 
@@ -284,3 +291,16 @@ async def test_repo_filter_collection(author_repo: AuthorAsyncRepository) -> Non
         author_repo (AuthorRepository): The author mock repository
     """
     await st.test_repo_filter_collection(author_repo=author_repo)
+
+
+async def test_repo_json_methods(
+    raw_rules_uuid: list[dict[str, Any]],
+    rule_repo: RuleAsyncRepository,
+) -> None:
+    """Test SQLALchemy Collection filter.
+
+    Args:
+        raw_rules_uuid (list[dict[str, Any]]): list of rules pre-seeded into the mock repository
+        rules_repo (AuthorAsyncRepository): The rules mock repository
+    """
+    await st.test_repo_json_methods(raw_rules_uuid=raw_rules_uuid, rule_repo=rule_repo)
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
@@ -1,5 +1,6 @@
 from __future__ import annotations
 
+import json
 from datetime import datetime
 from typing import TYPE_CHECKING, Any
 from uuid import UUID
@@ -87,6 +88,27 @@ def fx_raw_log_events_uuid() -> list[dict[str, Any]]:
     ]
 
 
+@pytest.fixture(name="raw_rules_uuid")
+def fx_raw_rules_uuid() -> list[dict[str, Any]]:
+    """Unstructured rules representations."""
+    return [
+        {
+            "id": "f34545b9-663c-4fce-915d-dd1ae9cea42a",
+            "name": "Initial loading rule.",
+            "config": json.dumps({"url": "https://litestar.dev", "setting_123": 1}),
+            "created": "2023-01-01T00:00:00",
+            "updated": "2023-02-01T00:00:00",
+        },
+        {
+            "id": "f34545b9-663c-4fce-915d-dd1ae9cea34b",
+            "name": "Secondary loading rule.",
+            "config": {"url": "https://litestar.dev", "bar": "foo", "setting_123": 4},
+            "created": "2023-02-01T00:00:00",
+            "updated": "2023-02-01T00:00:00",
+        },
+    ]
+
+
 @pytest.fixture(name="raw_authors_bigint")
 def fx_raw_authors_bigint() -> list[dict[str, Any]]:
     """Unstructured author representations."""
@@ -132,3 +154,24 @@ def fx_raw_log_events_bigint() -> list[dict[str, Any]]:
             "updated": "0001-01-01T00:00:00",
         },
     ]
+
+
+@pytest.fixture(name="raw_rules_bigint")
+def fx_raw_rules_bigint() -> list[dict[str, Any]]:
+    """Unstructured rules representations."""
+    return [
+        {
+            "id": 2025,
+            "name": "Initial loading rule.",
+            "config": json.dumps({"url": "https://litestar.dev", "setting_123": 1}),
+            "created": "2023-01-01T00:00:00",
+            "updated": "2023-02-01T00:00:00",
+        },
+        {
+            "id": 2024,
+            "name": "Secondary loading rule.",
+            "config": {"url": "https://litestar.dev", "bar": "foo", "setting_123": 4},
+            "created": "2023-02-01T00:00:00",
+            "updated": "2023-02-01T00:00:00",
+        },
+    ]
diff --git a/tests/contrib/sqlalchemy/repository/duckdb/test_sqlalchemy_duckdb_bigint.py b/tests/contrib/sqlalchemy/repository/duckdb/test_sqlalchemy_duckdb_bigint.py
--- a/tests/contrib/sqlalchemy/repository/duckdb/test_sqlalchemy_duckdb_bigint.py
+++ b/tests/contrib/sqlalchemy/repository/duckdb/test_sqlalchemy_duckdb_bigint.py
@@ -12,6 +12,7 @@
 from tests.contrib.sqlalchemy.models_bigint import (
     AuthorSyncRepository,
     BookSyncRepository,
+    RuleSyncRepository,
 )
 from tests.contrib.sqlalchemy.repository import sqlalchemy_sync_bigint_tests as st
 
@@ -44,10 +45,13 @@ def fx_engine(tmp_path: Path) -> Generator[Engine, None, None]:
     name="session",
 )
 def fx_session(
-    engine: Engine, raw_authors_bigint: list[dict[str, Any]], raw_books_bigint: list[dict[str, Any]]
+    engine: Engine,
+    raw_authors_bigint: list[dict[str, Any]],
+    raw_books_bigint: list[dict[str, Any]],
+    raw_rules_bigint: list[dict[str, Any]],
 ) -> Generator[Session, None, None]:
     session = sessionmaker(bind=engine)()
-    st.seed_db(engine, raw_authors_bigint, raw_books_bigint)
+    st.seed_db(engine, raw_authors_bigint, raw_books_bigint, raw_rules_bigint)
     try:
         yield session
     finally:
@@ -65,6 +69,11 @@ def fx_book_repo(session: Session) -> BookSyncRepository:
     return BookSyncRepository(session=session)
 
 
+@pytest.fixture(name="rule_repo")
+def fx_rule_repo(session: Session) -> RuleSyncRepository:
+    return RuleSyncRepository(session=session)
+
+
 def test_filter_by_kwargs_with_incorrect_attribute_name(author_repo: AuthorSyncRepository) -> None:
     """Test SQLALchemy filter by kwargs with invalid column name.
 
@@ -269,3 +278,16 @@ def test_repo_filter_collection(author_repo: AuthorSyncRepository) -> None:
         author_repo (AuthorRepository): The author mock repository
     """
     st.test_repo_filter_collection(author_repo=author_repo)
+
+
+def test_repo_json_methods(
+    raw_rules_bigint: list[dict[str, Any]],
+    rule_repo: RuleSyncRepository,
+) -> None:
+    """Test SQLALchemy Collection filter.
+
+    Args:
+        raw_rules_bigint (list[dict[str, Any]]): list of rules pre-seeded into the mock repository
+        rule_repo (RuleSyncRepository): The rules mock repository
+    """
+    st.test_repo_json_methods(raw_rules_bigint=raw_rules_bigint, rule_repo=rule_repo)
diff --git a/tests/contrib/sqlalchemy/repository/duckdb/test_sqlalchemy_duckdb_uuid.py b/tests/contrib/sqlalchemy/repository/duckdb/test_sqlalchemy_duckdb_uuid.py
--- a/tests/contrib/sqlalchemy/repository/duckdb/test_sqlalchemy_duckdb_uuid.py
+++ b/tests/contrib/sqlalchemy/repository/duckdb/test_sqlalchemy_duckdb_uuid.py
@@ -12,6 +12,7 @@
 from tests.contrib.sqlalchemy.models_uuid import (
     AuthorSyncRepository,
     BookSyncRepository,
+    RuleSyncRepository,
 )
 from tests.contrib.sqlalchemy.repository import sqlalchemy_sync_uuid_tests as st
 
@@ -44,10 +45,13 @@ def fx_engine(tmp_path: Path) -> Generator[Engine, None, None]:
     name="session",
 )
 def fx_session(
-    engine: Engine, raw_authors_uuid: list[dict[str, Any]], raw_books_uuid: list[dict[str, Any]]
+    engine: Engine,
+    raw_authors_uuid: list[dict[str, Any]],
+    raw_books_uuid: list[dict[str, Any]],
+    raw_rules_uuid: list[dict[str, Any]],
 ) -> Generator[Session, None, None]:
     session = sessionmaker(bind=engine)()
-    st.seed_db(engine, raw_authors_uuid, raw_books_uuid)
+    st.seed_db(engine, raw_authors_uuid, raw_books_uuid, raw_rules_uuid)
     try:
         yield session
     finally:
@@ -65,6 +69,11 @@ def fx_book_repo(session: Session) -> BookSyncRepository:
     return BookSyncRepository(session=session)
 
 
+@pytest.fixture(name="rule_repo")
+def fx_rule_repo(session: Session) -> RuleSyncRepository:
+    return RuleSyncRepository(session=session)
+
+
 def test_filter_by_kwargs_with_incorrect_attribute_name(author_repo: AuthorSyncRepository) -> None:
     """Test SQLALchemy filter by kwargs with invalid column name.
 
@@ -267,3 +276,16 @@ def test_repo_filter_collection(author_repo: AuthorSyncRepository) -> None:
         author_repo (AuthorRepository): The author mock repository
     """
     st.test_repo_filter_collection(author_repo=author_repo)
+
+
+def test_repo_json_methods(
+    raw_rules_uuid: list[dict[str, Any]],
+    rule_repo: RuleSyncRepository,
+) -> None:
+    """Test SQLALchemy Collection filter.
+
+    Args:
+        raw_rules_uuid (list[dict[str, Any]]): list of rules pre-seeded into the mock repository
+        rule_repo (RuleSyncRepository): The rules mock repository
+    """
+    st.test_repo_json_methods(raw_rules_uuid=raw_rules_uuid, rule_repo=rule_repo)
diff --git a/tests/contrib/sqlalchemy/repository/oracledb/test_sqlalchemy_oracledb_bigint.py b/tests/contrib/sqlalchemy/repository/oracledb/test_sqlalchemy_oracledb_bigint.py
--- a/tests/contrib/sqlalchemy/repository/oracledb/test_sqlalchemy_oracledb_bigint.py
+++ b/tests/contrib/sqlalchemy/repository/oracledb/test_sqlalchemy_oracledb_bigint.py
@@ -9,7 +9,7 @@
 from sqlalchemy import Engine, NullPool, create_engine
 from sqlalchemy.orm import Session, sessionmaker
 
-from tests.contrib.sqlalchemy.models_bigint import AuthorSyncRepository, BookSyncRepository
+from tests.contrib.sqlalchemy.models_bigint import AuthorSyncRepository, BookSyncRepository, RuleSyncRepository
 from tests.contrib.sqlalchemy.repository import sqlalchemy_sync_bigint_tests as st
 
 pytestmark = [
@@ -52,10 +52,13 @@ def fx_engine(docker_ip: str) -> Engine:
     name="session",
 )
 def fx_session(
-    engine: Engine, raw_authors_bigint: list[dict[str, Any]], raw_books_bigint: list[dict[str, Any]]
+    engine: Engine,
+    raw_authors_bigint: list[dict[str, Any]],
+    raw_books_bigint: list[dict[str, Any]],
+    raw_rules_bigint: list[dict[str, Any]],
 ) -> Generator[Session, None, None]:
     session = sessionmaker(bind=engine)()
-    st.seed_db(engine, raw_authors_bigint, raw_books_bigint)
+    st.seed_db(engine, raw_authors_bigint, raw_books_bigint, raw_rules_bigint)
     try:
         yield session
     finally:
@@ -73,6 +76,11 @@ def fx_book_repo(session: Session) -> BookSyncRepository:
     return BookSyncRepository(session=session)
 
 
+@pytest.fixture(name="rule_repo")
+def fx_rule_repo(session: Session) -> RuleSyncRepository:
+    return RuleSyncRepository(session=session)
+
+
 def test_filter_by_kwargs_with_incorrect_attribute_name(author_repo: AuthorSyncRepository) -> None:
     """Test SQLALchemy filter by kwargs with invalid column name.
 
@@ -278,3 +286,16 @@ def test_repo_filter_collection(author_repo: AuthorSyncRepository) -> None:
         author_repo (AuthorRepository): The author mock repository
     """
     st.test_repo_filter_collection(author_repo=author_repo)
+
+
+def test_repo_json_methods(
+    raw_rules_bigint: list[dict[str, Any]],
+    rule_repo: RuleSyncRepository,
+) -> None:
+    """Test SQLALchemy Collection filter.
+
+    Args:
+        raw_rules_bigint (list[dict[str, Any]]): list of rules pre-seeded into the mock repository
+        rule_repo (RuleSyncRepository): The rules mock repository
+    """
+    st.test_repo_json_methods(raw_rules_bigint=raw_rules_bigint, rule_repo=rule_repo)
diff --git a/tests/contrib/sqlalchemy/repository/oracledb/test_sqlalchemy_oracledb_uuid.py b/tests/contrib/sqlalchemy/repository/oracledb/test_sqlalchemy_oracledb_uuid.py
--- a/tests/contrib/sqlalchemy/repository/oracledb/test_sqlalchemy_oracledb_uuid.py
+++ b/tests/contrib/sqlalchemy/repository/oracledb/test_sqlalchemy_oracledb_uuid.py
@@ -12,6 +12,7 @@
 from tests.contrib.sqlalchemy.models_uuid import (
     AuthorSyncRepository,
     BookSyncRepository,
+    RuleSyncRepository,
 )
 from tests.contrib.sqlalchemy.repository import sqlalchemy_sync_uuid_tests as st
 
@@ -55,10 +56,13 @@ def fx_engine(docker_ip: str) -> Engine:
     name="session",
 )
 def fx_session(
-    engine: Engine, raw_authors_uuid: list[dict[str, Any]], raw_books_uuid: list[dict[str, Any]]
+    engine: Engine,
+    raw_authors_uuid: list[dict[str, Any]],
+    raw_books_uuid: list[dict[str, Any]],
+    raw_rules_uuid: list[dict[str, Any]],
 ) -> Generator[Session, None, None]:
     session = sessionmaker(bind=engine)()
-    st.seed_db(engine, raw_authors_uuid, raw_books_uuid)
+    st.seed_db(engine, raw_authors_uuid, raw_books_uuid, raw_rules_uuid)
     try:
         yield session
     finally:
@@ -76,6 +80,11 @@ def fx_book_repo(session: Session) -> BookSyncRepository:
     return BookSyncRepository(session=session)
 
 
+@pytest.fixture(name="rule_repo")
+def fx_rule_repo(session: Session) -> RuleSyncRepository:
+    return RuleSyncRepository(session=session)
+
+
 def test_filter_by_kwargs_with_incorrect_attribute_name(author_repo: AuthorSyncRepository) -> None:
     """Test SQLALchemy filter by kwargs with invalid column name.
 
@@ -278,3 +287,16 @@ def test_repo_filter_collection(author_repo: AuthorSyncRepository) -> None:
         author_repo (AuthorRepository): The author mock repository
     """
     st.test_repo_filter_collection(author_repo=author_repo)
+
+
+def test_repo_json_methods(
+    raw_rules_uuid: list[dict[str, Any]],
+    rule_repo: RuleSyncRepository,
+) -> None:
+    """Test SQLALchemy Collection filter.
+
+    Args:
+        raw_rules_uuid (list[dict[str, Any]]): list of rules pre-seeded into the mock repository
+        rule_repo (RuleSyncRepository): The rules mock repository
+    """
+    st.test_repo_json_methods(raw_rules_uuid=raw_rules_uuid, rule_repo=rule_repo)
diff --git a/tests/contrib/sqlalchemy/repository/psycopg/test_sqlalchemy_psycopg_bigint_async.py b/tests/contrib/sqlalchemy/repository/psycopg/test_sqlalchemy_psycopg_bigint_async.py
--- a/tests/contrib/sqlalchemy/repository/psycopg/test_sqlalchemy_psycopg_bigint_async.py
+++ b/tests/contrib/sqlalchemy/repository/psycopg/test_sqlalchemy_psycopg_bigint_async.py
@@ -17,6 +17,7 @@
 from tests.contrib.sqlalchemy.models_bigint import (
     AuthorAsyncRepository,
     BookAsyncRepository,
+    RuleAsyncRepository,
 )
 from tests.contrib.sqlalchemy.repository import sqlalchemy_async_bigint_tests as st
 
@@ -57,10 +58,13 @@ async def fx_engine(docker_ip: str) -> AsyncEngine:
     name="session",
 )
 async def fx_session(
-    engine: AsyncEngine, raw_authors_bigint: list[dict[str, Any]], raw_books_bigint: list[dict[str, Any]]
+    engine: AsyncEngine,
+    raw_authors_bigint: list[dict[str, Any]],
+    raw_books_bigint: list[dict[str, Any]],
+    raw_rules_bigint: list[dict[str, Any]],
 ) -> AsyncGenerator[AsyncSession, None]:
     session = async_sessionmaker(bind=engine)()
-    await st.seed_db(engine, raw_authors_bigint, raw_books_bigint)
+    await st.seed_db(engine, raw_authors_bigint, raw_books_bigint, raw_rules_bigint)
     try:
         yield session
     finally:
@@ -78,6 +82,11 @@ def fx_book_repo(session: AsyncSession) -> BookAsyncRepository:
     return BookAsyncRepository(session=session)
 
 
+@pytest.fixture(name="rule_repo")
+def fx_rule_repo(session: AsyncSession) -> RuleAsyncRepository:
+    return RuleAsyncRepository(session=session)
+
+
 def test_filter_by_kwargs_with_incorrect_attribute_name(author_repo: AuthorAsyncRepository) -> None:
     """Test SQLALchemy filter by kwargs with invalid column name.
 
@@ -284,3 +293,16 @@ async def test_repo_filter_collection(author_repo: AuthorAsyncRepository) -> Non
         author_repo (AuthorRepository): The author mock repository
     """
     await st.test_repo_filter_collection(author_repo=author_repo)
+
+
+async def test_repo_json_methods(
+    raw_rules_bigint: list[dict[str, Any]],
+    rule_repo: RuleAsyncRepository,
+) -> None:
+    """Test SQLALchemy Collection filter.
+
+    Args:
+        raw_rules_bigint (list[dict[str, Any]]): list of rules pre-seeded into the mock repository
+        rule_repo (AuthorAsyncRepository): The rules mock repository
+    """
+    await st.test_repo_json_methods(raw_rules_bigint=raw_rules_bigint, rule_repo=rule_repo)
diff --git a/tests/contrib/sqlalchemy/repository/psycopg/test_sqlalchemy_psycopg_bigint_sync.py b/tests/contrib/sqlalchemy/repository/psycopg/test_sqlalchemy_psycopg_bigint_sync.py
--- a/tests/contrib/sqlalchemy/repository/psycopg/test_sqlalchemy_psycopg_bigint_sync.py
+++ b/tests/contrib/sqlalchemy/repository/psycopg/test_sqlalchemy_psycopg_bigint_sync.py
@@ -12,6 +12,7 @@
 from tests.contrib.sqlalchemy.models_bigint import (
     AuthorSyncRepository,
     BookSyncRepository,
+    RuleSyncRepository,
 )
 from tests.contrib.sqlalchemy.repository import sqlalchemy_sync_bigint_tests as st
 
@@ -52,10 +53,13 @@ def fx_engine(docker_ip: str) -> Engine:
     name="session",
 )
 def fx_session(
-    engine: Engine, raw_authors_bigint: list[dict[str, Any]], raw_books_bigint: list[dict[str, Any]]
+    engine: Engine,
+    raw_authors_bigint: list[dict[str, Any]],
+    raw_books_bigint: list[dict[str, Any]],
+    raw_rules_bigint: list[dict[str, Any]],
 ) -> Generator[Session, None, None]:
     session = sessionmaker(bind=engine)()
-    st.seed_db(engine, raw_authors_bigint, raw_books_bigint)
+    st.seed_db(engine, raw_authors_bigint, raw_books_bigint, raw_rules_bigint)
     try:
         yield session
     finally:
@@ -73,6 +77,11 @@ def fx_book_repo(session: Session) -> BookSyncRepository:
     return BookSyncRepository(session=session)
 
 
+@pytest.fixture(name="rule_repo")
+def fx_rule_repo(session: Session) -> RuleSyncRepository:
+    return RuleSyncRepository(session=session)
+
+
 def test_filter_by_kwargs_with_incorrect_attribute_name(author_repo: AuthorSyncRepository) -> None:
     """Test SQLALchemy filter by kwargs with invalid column name.
 
@@ -277,3 +286,16 @@ def test_repo_filter_collection(author_repo: AuthorSyncRepository) -> None:
         author_repo (AuthorRepository): The author mock repository
     """
     st.test_repo_filter_collection(author_repo=author_repo)
+
+
+def test_repo_json_methods(
+    raw_rules_bigint: list[dict[str, Any]],
+    rule_repo: RuleSyncRepository,
+) -> None:
+    """Test SQLALchemy Collection filter.
+
+    Args:
+        raw_rules_bigint (list[dict[str, Any]]): list of rules pre-seeded into the mock repository
+        rule_repo (RuleSyncRepository): The rules mock repository
+    """
+    st.test_repo_json_methods(raw_rules_bigint=raw_rules_bigint, rule_repo=rule_repo)
diff --git a/tests/contrib/sqlalchemy/repository/psycopg/test_sqlalchemy_psycopg_uuid_async.py b/tests/contrib/sqlalchemy/repository/psycopg/test_sqlalchemy_psycopg_uuid_async.py
--- a/tests/contrib/sqlalchemy/repository/psycopg/test_sqlalchemy_psycopg_uuid_async.py
+++ b/tests/contrib/sqlalchemy/repository/psycopg/test_sqlalchemy_psycopg_uuid_async.py
@@ -17,6 +17,7 @@
 from tests.contrib.sqlalchemy.models_uuid import (
     AuthorAsyncRepository,
     BookAsyncRepository,
+    RuleAsyncRepository,
 )
 from tests.contrib.sqlalchemy.repository import sqlalchemy_async_uuid_tests as st
 
@@ -57,10 +58,13 @@ async def fx_engine(docker_ip: str) -> AsyncEngine:
     name="session",
 )
 async def fx_session(
-    engine: AsyncEngine, raw_authors_uuid: list[dict[str, Any]], raw_books_bigint: list[dict[str, Any]]
+    engine: AsyncEngine,
+    raw_authors_uuid: list[dict[str, Any]],
+    raw_books_uuid: list[dict[str, Any]],
+    raw_rules_uuid: list[dict[str, Any]],
 ) -> AsyncGenerator[AsyncSession, None]:
     session = async_sessionmaker(bind=engine)()
-    await st.seed_db(engine, raw_authors_uuid, raw_books_bigint)
+    await st.seed_db(engine, raw_authors_uuid, raw_books_uuid, raw_rules_uuid)
     try:
         yield session
     finally:
@@ -78,6 +82,11 @@ def fx_book_repo(session: AsyncSession) -> BookAsyncRepository:
     return BookAsyncRepository(session=session)
 
 
+@pytest.fixture(name="rule_repo")
+def fx_rule_repo(session: AsyncSession) -> RuleAsyncRepository:
+    return RuleAsyncRepository(session=session)
+
+
 def test_filter_by_kwargs_with_incorrect_attribute_name(author_repo: AuthorAsyncRepository) -> None:
     """Test SQLALchemy filter by kwargs with invalid column name.
 
@@ -282,3 +291,16 @@ async def test_repo_filter_collection(author_repo: AuthorAsyncRepository) -> Non
         author_repo (AuthorRepository): The author mock repository
     """
     await st.test_repo_filter_collection(author_repo=author_repo)
+
+
+async def test_repo_json_methods(
+    raw_rules_uuid: list[dict[str, Any]],
+    rule_repo: RuleAsyncRepository,
+) -> None:
+    """Test SQLALchemy Collection filter.
+
+    Args:
+        raw_rules_uuid (list[dict[str, Any]]): list of rules pre-seeded into the mock repository
+        rules_repo (AuthorAsyncRepository): The rules mock repository
+    """
+    await st.test_repo_json_methods(raw_rules_uuid=raw_rules_uuid, rule_repo=rule_repo)
diff --git a/tests/contrib/sqlalchemy/repository/psycopg/test_sqlalchemy_psycopg_uuid_sync.py b/tests/contrib/sqlalchemy/repository/psycopg/test_sqlalchemy_psycopg_uuid_sync.py
--- a/tests/contrib/sqlalchemy/repository/psycopg/test_sqlalchemy_psycopg_uuid_sync.py
+++ b/tests/contrib/sqlalchemy/repository/psycopg/test_sqlalchemy_psycopg_uuid_sync.py
@@ -12,6 +12,7 @@
 from tests.contrib.sqlalchemy.models_uuid import (
     AuthorSyncRepository,
     BookSyncRepository,
+    RuleSyncRepository,
 )
 from tests.contrib.sqlalchemy.repository import sqlalchemy_sync_uuid_tests as st
 
@@ -52,10 +53,13 @@ def fx_engine(docker_ip: str) -> Engine:
     name="session",
 )
 def fx_session(
-    engine: Engine, raw_authors_uuid: list[dict[str, Any]], raw_books_uuid: list[dict[str, Any]]
+    engine: Engine,
+    raw_authors_uuid: list[dict[str, Any]],
+    raw_books_uuid: list[dict[str, Any]],
+    raw_rules_uuid: list[dict[str, Any]],
 ) -> Generator[Session, None, None]:
     session = sessionmaker(bind=engine)()
-    st.seed_db(engine, raw_authors_uuid, raw_books_uuid)
+    st.seed_db(engine, raw_authors_uuid, raw_books_uuid, raw_rules_uuid)
     try:
         yield session
     finally:
@@ -73,6 +77,11 @@ def fx_book_repo(session: Session) -> BookSyncRepository:
     return BookSyncRepository(session=session)
 
 
+@pytest.fixture(name="rule_repo")
+def fx_rule_repo(session: Session) -> RuleSyncRepository:
+    return RuleSyncRepository(session=session)
+
+
 def test_filter_by_kwargs_with_incorrect_attribute_name(author_repo: AuthorSyncRepository) -> None:
     """Test SQLALchemy filter by kwargs with invalid column name.
 
@@ -278,3 +287,16 @@ def test_repo_filter_collection(author_repo: AuthorSyncRepository) -> None:
         author_repo (AuthorRepository): The author mock repository
     """
     st.test_repo_filter_collection(author_repo=author_repo)
+
+
+def test_repo_json_methods(
+    raw_rules_uuid: list[dict[str, Any]],
+    rule_repo: RuleSyncRepository,
+) -> None:
+    """Test SQLALchemy Collection filter.
+
+    Args:
+        raw_rules_uuid (list[dict[str, Any]]): list of rules pre-seeded into the mock repository
+        rule_repo (RuleSyncRepository): The rules mock repository
+    """
+    st.test_repo_json_methods(raw_rules_uuid=raw_rules_uuid, rule_repo=rule_repo)
diff --git a/tests/contrib/sqlalchemy/repository/spanner/test_sqlalchemy_spanner_uuid.py b/tests/contrib/sqlalchemy/repository/spanner/test_sqlalchemy_spanner_uuid.py
--- a/tests/contrib/sqlalchemy/repository/spanner/test_sqlalchemy_spanner_uuid.py
+++ b/tests/contrib/sqlalchemy/repository/spanner/test_sqlalchemy_spanner_uuid.py
@@ -13,7 +13,9 @@
 from tests.contrib.sqlalchemy.models_uuid import (
     AuthorSyncRepository,
     BookSyncRepository,
+    RuleSyncRepository,
     UUIDAuthor,
+    UUIDRule,
 )
 from tests.contrib.sqlalchemy.repository import sqlalchemy_sync_uuid_tests as st
 
@@ -21,10 +23,20 @@
     pytest.mark.skipif(sys.platform != "linux", reason="docker not available on this platform"),
     pytest.mark.usefixtures("spanner_service"),
     pytest.mark.sqlalchemy_integration,
-    pytest.mark.sqlalchemy_psycopg_sync,
+    pytest.mark.sqlalchemy_spanner,
 ]
 
 
+@pytest.fixture()
+def set_spanner_emulator_host(monkeypatch: pytest.MonkeyPatch) -> None:
+    monkeypatch.setenv("SPANNER_EMULATOR_HOST", "localhost:9010")
+
+
+@pytest.fixture()
+def set_google_cloud_project(monkeypatch: pytest.MonkeyPatch) -> None:
+    monkeypatch.setenv("GOOGLE_CLOUD_PROJECT", "emulator-test-project")
+
+
 @pytest.fixture(name="engine")
 def fx_engine(docker_ip: str) -> Engine:
     """Postgresql instance for end-to-end testing.
@@ -35,8 +47,6 @@ def fx_engine(docker_ip: str) -> Engine:
     Returns:
         Async SQLAlchemy engine instance.
     """
-    os.environ["SPANNER_EMULATOR_HOST"] = "localhost:9010"
-    os.environ["GOOGLE_CLOUD_PROJECT"] = "emulator-test-project"
     return create_engine(
         "spanner+spanner:///projects/emulator-test-project/instances/test-instance/databases/test-database",
         echo=True,
@@ -45,12 +55,18 @@ def fx_engine(docker_ip: str) -> Engine:
 
 @pytest.fixture(name="session")
 def fx_session(
-    engine: Engine, raw_authors_uuid: list[dict[str, Any]], raw_books_uuid: list[dict[str, Any]]
+    engine: Engine,
+    raw_authors_uuid: list[dict[str, Any]],
+    raw_books_uuid: list[dict[str, Any]],
+    raw_rules_uuid: list[dict[str, Any]],
 ) -> Generator[Session, None, None]:
     for raw_author in raw_authors_uuid:
         raw_author["dob"] = datetime.strptime(raw_author["dob"], "%Y-%m-%d").date()
         raw_author["created"] = datetime.strptime(raw_author["created"], "%Y-%m-%dT%H:%M:%S")
         raw_author["updated"] = datetime.strptime(raw_author["updated"], "%Y-%m-%dT%H:%M:%S")
+    for raw_rule in raw_rules_uuid:
+        raw_rule["created"] = datetime.strptime(raw_rule["created"], "%Y-%m-%dT%H:%M:%S")
+        raw_rule["updated"] = datetime.strptime(raw_rule["updated"], "%Y-%m-%dT%H:%M:%S")
     with engine.begin() as txn:
         objs = []
         for tbl in UUIDAuthor.registry.metadata.sorted_tables:
@@ -60,9 +76,15 @@ def fx_session(
 
     session = sessionmaker(bind=engine)()
     try:
-        repo = AuthorSyncRepository(session=session)
+        author_repo = AuthorSyncRepository(session=session)
         for author in raw_authors_uuid:
-            _ = repo.get_or_create("name", **author)
+            _ = author_repo.get_or_create(match_fields="name", **author)
+        if not bool(os.environ.get("SPANNER_EMULATOR_HOST")):
+            rule_repo = RuleSyncRepository(session=session)
+            for rule in raw_rules_uuid:
+                _ = rule_repo.add(
+                    UUIDRule(**rule),
+                )
         yield session
     finally:
         session.rollback()
@@ -81,6 +103,11 @@ def fx_book_repo(session: Session) -> BookSyncRepository:
     return BookSyncRepository(session=session)
 
 
+@pytest.fixture(name="rule_repo")
+def fx_rule_repo(session: Session) -> RuleSyncRepository:
+    return RuleSyncRepository(session=session)
+
+
 def test_filter_by_kwargs_with_incorrect_attribute_name(author_repo: AuthorSyncRepository) -> None:
     """Test SQLALchemy filter by kwargs with invalid column name.
 
@@ -151,6 +178,7 @@ def test_repo_add_many_method(raw_authors_uuid: list[dict[str, Any]], author_rep
 
 
 # there's an emulator bug that causes this one to fail.
+@pytest.mark.skipif(bool(os.environ.get("SPANNER_EMULATOR_HOST")), reason="Skipped on emulator")
 @pytest.mark.xfail
 def test_repo_update_many_method(author_repo: AuthorSyncRepository) -> None:
     """Test SQLALchemy Update Many.
@@ -285,3 +313,21 @@ def test_repo_filter_collection(author_repo: AuthorSyncRepository) -> None:
         author_repo (AuthorRepository): The author mock repository
     """
     st.test_repo_filter_collection(author_repo=author_repo)
+
+
+# there's an emulator bug that causes this one to fail.
+# The current google tests disable JSON tests when using the emulator.
+# https://github.com/googleapis/python-spanner-sqlalchemy/blob/main/test/test_suite_20.py#L2853
+@pytest.mark.skipif(bool(os.environ.get("SPANNER_EMULATOR_HOST")), reason="Skipped on emulator")
+@pytest.mark.xfail
+def test_repo_json_methods(
+    raw_rules_uuid: list[dict[str, Any]],
+    rule_repo: RuleSyncRepository,
+) -> None:
+    """Test SQLALchemy Collection filter.
+
+    Args:
+        raw_rules_uuid (list[dict[str, Any]]): list of rules pre-seeded into the mock repository
+        rule_repo (RuleSyncRepository): The rules mock repository
+    """
+    st.test_repo_json_methods(raw_rules_uuid=raw_rules_uuid, rule_repo=rule_repo)
diff --git a/tests/contrib/sqlalchemy/repository/sqlalchemy_async_bigint_tests.py b/tests/contrib/sqlalchemy/repository/sqlalchemy_async_bigint_tests.py
--- a/tests/contrib/sqlalchemy/repository/sqlalchemy_async_bigint_tests.py
+++ b/tests/contrib/sqlalchemy/repository/sqlalchemy_async_bigint_tests.py
@@ -11,13 +11,20 @@
 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_bigint import AuthorAsyncRepository, BigIntAuthor, BookAsyncRepository
+from tests.contrib.sqlalchemy.models_bigint import (
+    AuthorAsyncRepository,
+    BigIntAuthor,
+    BigIntRule,
+    BookAsyncRepository,
+    RuleAsyncRepository,
+)
 
 
 async def seed_db(
     engine: AsyncEngine,
     raw_authors_bigint: list[dict[str, Any]],
     raw_books_bigint: list[dict[str, Any]],
+    raw_rules_bigint: list[dict[str, Any]],
 ) -> None:
     """Populate test database with sample data.
 
@@ -29,10 +36,15 @@ async def seed_db(
         raw_author["dob"] = datetime.strptime(raw_author["dob"], "%Y-%m-%d").date()
         raw_author["created"] = datetime.strptime(raw_author["created"], "%Y-%m-%dT%H:%M:%S")
         raw_author["updated"] = datetime.strptime(raw_author["updated"], "%Y-%m-%dT%H:%M:%S")
+    for raw_author in raw_rules_bigint:
+        raw_author["created"] = datetime.strptime(raw_author["created"], "%Y-%m-%dT%H:%M:%S")
+        raw_author["updated"] = datetime.strptime(raw_author["updated"], "%Y-%m-%dT%H:%M:%S")
+
     async with engine.begin() as conn:
         await conn.run_sync(base.orm_registry.metadata.drop_all)
         await conn.run_sync(base.orm_registry.metadata.create_all)
         await conn.execute(insert(BigIntAuthor).values(raw_authors_bigint))
+        await conn.execute(insert(BigIntRule).values(raw_rules_bigint))
 
 
 def test_filter_by_kwargs_with_incorrect_attribute_name(author_repo: AuthorAsyncRepository) -> None:
@@ -359,3 +371,43 @@ async def test_repo_filter_collection(author_repo: AuthorAsyncRepository) -> Non
 
     existing_obj = await author_repo.list(CollectionFilter(field_name="id", values=[2024]))
     assert existing_obj[0].name == "Leo Tolstoy"
+
+
+async def test_repo_json_methods(
+    raw_rules_bigint: list[dict[str, Any]],
+    rule_repo: RuleAsyncRepository,
+) -> None:
+    """Test SQLALchemy JSON.
+
+    Args:
+        raw_rules_bigint (list[dict[str, Any]]): list of rules pre-seeded into the mock repository
+        rule_repo (AuthorAsyncRepository): The rules mock repository
+    """
+    exp_count = len(raw_rules_bigint) + 1
+    new_rule = BigIntRule(name="Testing", config={"an": "object"})
+    obj = await rule_repo.add(new_rule)
+    count = await rule_repo.count()
+    assert exp_count == count
+    assert isinstance(obj, BigIntRule)
+    assert new_rule.name == obj.name
+    assert new_rule.config == obj.config
+    assert obj.id is not None
+    obj.config = {"the": "update"}
+    updated = await rule_repo.update(obj)
+    assert obj.config == updated.config
+
+    get_obj, get_created = await rule_repo.get_or_create(
+        match_fields=["name"],
+        name="Secondary loading rule.",
+        config={"another": "object"},
+    )
+    assert get_created is False
+    assert get_obj.id is not None
+    assert get_obj.config == {"another": "object"}
+
+    new_obj, new_created = await rule_repo.get_or_create(
+        match_fields=["name"], name="New rule.", config={"new": "object"}
+    )
+    assert new_created is True
+    assert new_obj.id is not None
+    assert new_obj.config == {"new": "object"}
diff --git a/tests/contrib/sqlalchemy/repository/sqlalchemy_async_uuid_tests.py b/tests/contrib/sqlalchemy/repository/sqlalchemy_async_uuid_tests.py
--- a/tests/contrib/sqlalchemy/repository/sqlalchemy_async_uuid_tests.py
+++ b/tests/contrib/sqlalchemy/repository/sqlalchemy_async_uuid_tests.py
@@ -14,13 +14,20 @@
 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_uuid import AuthorAsyncRepository, BookAsyncRepository, UUIDAuthor
+from tests.contrib.sqlalchemy.models_uuid import (
+    AuthorAsyncRepository,
+    BookAsyncRepository,
+    RuleAsyncRepository,
+    UUIDAuthor,
+    UUIDRule,
+)
 
 
 async def seed_db(
     engine: AsyncEngine,
     raw_authors_uuid: list[dict[str, Any]],
     raw_books_uuid: list[dict[str, Any]],
+    raw_rules_uuid: list[dict[str, Any]],
 ) -> None:
     """Populate test database with sample data.
 
@@ -32,11 +39,15 @@ async def seed_db(
         raw_author["dob"] = datetime.strptime(raw_author["dob"], "%Y-%m-%d").date()
         raw_author["created"] = datetime.strptime(raw_author["created"], "%Y-%m-%dT%H:%M:%S")
         raw_author["updated"] = datetime.strptime(raw_author["updated"], "%Y-%m-%dT%H:%M:%S")
+    for raw_author in raw_rules_uuid:
+        raw_author["created"] = datetime.strptime(raw_author["created"], "%Y-%m-%dT%H:%M:%S")
+        raw_author["updated"] = datetime.strptime(raw_author["updated"], "%Y-%m-%dT%H:%M:%S")
 
     async with engine.begin() as conn:
         await conn.run_sync(base.orm_registry.metadata.drop_all)
         await conn.run_sync(base.orm_registry.metadata.create_all)
         await conn.execute(insert(UUIDAuthor).values(raw_authors_uuid))
+        await conn.execute(insert(UUIDRule).values(raw_rules_uuid))
 
 
 def test_filter_by_kwargs_with_incorrect_attribute_name(author_repo: AuthorAsyncRepository) -> None:
@@ -374,3 +385,41 @@ async def test_repo_filter_collection(author_repo: AuthorAsyncRepository) -> Non
         CollectionFilter(field_name="id", values=[UUID("5ef29f3c-3560-4d15-ba6b-a2e5c721e4d2")])
     )
     assert existing_obj[0].name == "Leo Tolstoy"
+
+
+async def test_repo_json_methods(
+    raw_rules_uuid: list[dict[str, Any]],
+    rule_repo: RuleAsyncRepository,
+) -> None:
+    """Test SQLALchemy JSON.
+
+    Args:
+        raw_rules_uuid (list[dict[str, Any]]): list of rules pre-seeded into the mock repository
+        rules_repo (AuthorSyncRepository): The rules mock repository
+    """
+    exp_count = len(raw_rules_uuid) + 1
+    new_rule = UUIDRule(name="Testing", config={"an": "object"})
+    obj = await rule_repo.add(new_rule)
+    count = await rule_repo.count()
+    assert exp_count == count
+    assert isinstance(obj, UUIDRule)
+    assert new_rule.name == obj.name
+    assert new_rule.config == obj.config
+    assert obj.id is not None
+    obj.config = {"the": "update"}
+    updated = await rule_repo.update(obj)
+    assert obj.config == updated.config
+
+    get_obj, get_created = await rule_repo.get_or_create(
+        match_fields=["name"], name="Secondary loading rule.", config={"another": "object"}
+    )
+    assert get_created is False
+    assert get_obj.id is not None
+    assert get_obj.config == {"another": "object"}
+
+    new_obj, new_created = await rule_repo.get_or_create(
+        match_fields=["name"], name="New rule.", config={"new": "object"}
+    )
+    assert new_created is True
+    assert new_obj.id is not None
+    assert new_obj.config == {"new": "object"}
diff --git a/tests/contrib/sqlalchemy/repository/sqlalchemy_sync_bigint_tests.py b/tests/contrib/sqlalchemy/repository/sqlalchemy_sync_bigint_tests.py
--- a/tests/contrib/sqlalchemy/repository/sqlalchemy_sync_bigint_tests.py
+++ b/tests/contrib/sqlalchemy/repository/sqlalchemy_sync_bigint_tests.py
@@ -10,13 +10,20 @@
 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_bigint import AuthorSyncRepository, BigIntAuthor, BookSyncRepository
+from tests.contrib.sqlalchemy.models_bigint import (
+    AuthorSyncRepository,
+    BigIntAuthor,
+    BigIntRule,
+    BookSyncRepository,
+    RuleSyncRepository,
+)
 
 
 def seed_db(
     engine: Engine,
     raw_authors_bigint: list[dict[str, Any]],
     raw_books_bigint: list[dict[str, Any]],
+    raw_rules_bigint: list[dict[str, Any]],
 ) -> None:
     """Populate test database with sample data.
 
@@ -28,12 +35,17 @@ def seed_db(
         raw_author["dob"] = datetime.strptime(raw_author["dob"], "%Y-%m-%d").date()
         raw_author["created"] = datetime.strptime(raw_author["created"], "%Y-%m-%dT%H:%M:%S")
         raw_author["updated"] = datetime.strptime(raw_author["updated"], "%Y-%m-%dT%H:%M:%S")
+    for raw_rule in raw_rules_bigint:
+        raw_rule["created"] = datetime.strptime(raw_rule["created"], "%Y-%m-%dT%H:%M:%S")
+        raw_rule["updated"] = datetime.strptime(raw_rule["updated"], "%Y-%m-%dT%H:%M:%S")
 
     with engine.begin() as conn:
         base.orm_registry.metadata.drop_all(conn)
         base.orm_registry.metadata.create_all(conn)
         for author in raw_authors_bigint:
             conn.execute(insert(BigIntAuthor).values(author))
+        for rule in raw_rules_bigint:
+            conn.execute(insert(BigIntRule).values(rule))
 
 
 def test_filter_by_kwargs_with_incorrect_attribute_name(author_repo: AuthorSyncRepository) -> None:
@@ -358,3 +370,41 @@ def test_repo_filter_collection(author_repo: AuthorSyncRepository) -> None:
 
     existing_obj = author_repo.list(CollectionFilter(field_name="id", values=[2024]))
     assert existing_obj[0].name == "Leo Tolstoy"
+
+
+def test_repo_json_methods(
+    raw_rules_bigint: list[dict[str, Any]],
+    rule_repo: RuleSyncRepository,
+) -> None:
+    """Test SQLALchemy JSON.
+
+    Args:
+        raw_rules_bigint (list[dict[str, Any]]): list of rules pre-seeded into the mock repository
+        rule_repo (AuthorSyncRepository): The rules mock repository
+    """
+    exp_count = len(raw_rules_bigint) + 1
+    new_rule = BigIntRule(name="Testing", config={"an": "object"})
+    obj = rule_repo.add(new_rule)
+    count = rule_repo.count()
+    assert exp_count == count
+    assert isinstance(obj, BigIntRule)
+    assert new_rule.name == obj.name
+    assert new_rule.config == obj.config
+    assert obj.id is not None
+    obj.config = {"the": "update"}
+    updated = rule_repo.update(obj)
+    assert obj.config == updated.config
+
+    get_obj, get_created = rule_repo.get_or_create(
+        match_fields=["name"],
+        name="Secondary loading rule.",
+        config={"another": "object"},
+    )
+    assert get_created is False
+    assert get_obj.id is not None
+    assert get_obj.config == {"another": "object"}
+
+    new_obj, new_created = rule_repo.get_or_create(match_fields=["name"], name="New rule.", config={"new": "object"})
+    assert new_created is True
+    assert new_obj.id is not None
+    assert new_obj.config == {"new": "object"}
diff --git a/tests/contrib/sqlalchemy/repository/sqlalchemy_sync_uuid_tests.py b/tests/contrib/sqlalchemy/repository/sqlalchemy_sync_uuid_tests.py
--- a/tests/contrib/sqlalchemy/repository/sqlalchemy_sync_uuid_tests.py
+++ b/tests/contrib/sqlalchemy/repository/sqlalchemy_sync_uuid_tests.py
@@ -11,13 +11,20 @@
 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_uuid import AuthorSyncRepository, BookSyncRepository, UUIDAuthor
+from tests.contrib.sqlalchemy.models_uuid import (
+    AuthorSyncRepository,
+    BookSyncRepository,
+    RuleSyncRepository,
+    UUIDAuthor,
+    UUIDRule,
+)
 
 
 def seed_db(
     engine: Engine,
     raw_authors_uuid: list[dict[str, Any]],
     raw_books_uuid: list[dict[str, Any]],
+    raw_rules_uuid: list[dict[str, Any]],
 ) -> None:
     """Populate test database with sample data.
 
@@ -29,6 +36,9 @@ def seed_db(
         raw_author["dob"] = datetime.strptime(raw_author["dob"], "%Y-%m-%d").date()
         raw_author["created"] = datetime.strptime(raw_author["created"], "%Y-%m-%dT%H:%M:%S")
         raw_author["updated"] = datetime.strptime(raw_author["updated"], "%Y-%m-%dT%H:%M:%S")
+    for raw_author in raw_rules_uuid:
+        raw_author["created"] = datetime.strptime(raw_author["created"], "%Y-%m-%dT%H:%M:%S")
+        raw_author["updated"] = datetime.strptime(raw_author["updated"], "%Y-%m-%dT%H:%M:%S")
 
     with engine.begin() as conn:
         base.orm_registry.metadata.drop_all(conn)
@@ -36,6 +46,8 @@ def seed_db(
     with engine.begin() as conn:
         for author in raw_authors_uuid:
             conn.execute(insert(UUIDAuthor).values(author))
+        for rule in raw_rules_uuid:
+            conn.execute(insert(UUIDRule).values(rule))
 
 
 def test_filter_by_kwargs_with_incorrect_attribute_name(author_repo: AuthorSyncRepository) -> None:
@@ -373,3 +385,40 @@ def test_repo_filter_collection(author_repo: AuthorSyncRepository) -> None:
         CollectionFilter(field_name="id", values=[UUID("5ef29f3c-3560-4d15-ba6b-a2e5c721e4d2")])
     )
     assert existing_obj[0].name == "Leo Tolstoy"
+
+
+def test_repo_json_methods(
+    raw_rules_uuid: list[dict[str, Any]],
+    rule_repo: RuleSyncRepository,
+) -> None:
+    """Test SQLALchemy JSON.
+
+    Args:
+        raw_rules_uuid (list[dict[str, Any]]): list of rules pre-seeded into the mock repository
+        rules_repo (AuthorSyncRepository): The rules mock repository
+    """
+    exp_count = len(raw_rules_uuid) + 1
+    new_rule = UUIDRule(name="Testing", config={"an": "object"})
+    obj = rule_repo.add(new_rule)
+    count = rule_repo.count()
+    assert exp_count == count
+    assert isinstance(obj, UUIDRule)
+    assert new_rule.name == obj.name
+    assert new_rule.config == obj.config
+    assert obj.id is not None
+
+    obj.config = {"the": "update"}
+    updated = rule_repo.update(obj)
+    assert obj.config == updated.config
+
+    get_obj, get_created = rule_repo.get_or_create(
+        match_fields=["name"], name="Secondary loading rule.", config={"another": "object"}
+    )
+    assert get_created is False
+    assert get_obj.id is not None
+    assert get_obj.config == {"another": "object"}
+
+    new_obj, new_created = rule_repo.get_or_create(match_fields=["name"], name="New rule.", config={"new": "object"})
+    assert new_created is True
+    assert new_obj.id is not None
+    assert new_obj.config == {"new": "object"}
diff --git a/tests/contrib/sqlalchemy/repository/sqlite/test_sqlalchemy_sqlite_bigint.py b/tests/contrib/sqlalchemy/repository/sqlite/test_sqlalchemy_sqlite_bigint.py
--- a/tests/contrib/sqlalchemy/repository/sqlite/test_sqlalchemy_sqlite_bigint.py
+++ b/tests/contrib/sqlalchemy/repository/sqlite/test_sqlalchemy_sqlite_bigint.py
@@ -11,6 +11,7 @@
 from tests.contrib.sqlalchemy.models_bigint import (
     AuthorSyncRepository,
     BookSyncRepository,
+    RuleSyncRepository,
 )
 from tests.contrib.sqlalchemy.repository import sqlalchemy_sync_bigint_tests as st
 
@@ -39,10 +40,13 @@ def fx_engine(tmp_path: Path) -> Generator[Engine, None, None]:
     name="session",
 )
 def fx_session(
-    engine: Engine, raw_authors_bigint: list[dict[str, Any]], raw_books_bigint: list[dict[str, Any]]
+    engine: Engine,
+    raw_authors_bigint: list[dict[str, Any]],
+    raw_books_bigint: list[dict[str, Any]],
+    raw_rules_bigint: list[dict[str, Any]],
 ) -> Generator[Session, None, None]:
     session = sessionmaker(bind=engine)()
-    st.seed_db(engine, raw_authors_bigint, raw_books_bigint)
+    st.seed_db(engine, raw_authors_bigint, raw_books_bigint, raw_rules_bigint)
     try:
         yield session
     finally:
@@ -60,6 +64,11 @@ def fx_book_repo(session: Session) -> BookSyncRepository:
     return BookSyncRepository(session=session)
 
 
+@pytest.fixture(name="rule_repo")
+def fx_rule_repo(session: Session) -> RuleSyncRepository:
+    return RuleSyncRepository(session=session)
+
+
 def test_filter_by_kwargs_with_incorrect_attribute_name(author_repo: AuthorSyncRepository) -> None:
     """Test SQLALchemy filter by kwargs with invalid column name.
 
@@ -265,3 +274,16 @@ def test_repo_filter_collection(author_repo: AuthorSyncRepository) -> None:
         author_repo (AuthorRepository): The author mock repository
     """
     st.test_repo_filter_collection(author_repo=author_repo)
+
+
+def test_repo_json_methods(
+    raw_rules_bigint: list[dict[str, Any]],
+    rule_repo: RuleSyncRepository,
+) -> None:
+    """Test SQLALchemy Collection filter.
+
+    Args:
+        raw_rules_bigint (list[dict[str, Any]]): list of rules pre-seeded into the mock repository
+        rule_repo (RuleSyncRepository): The rules mock repository
+    """
+    st.test_repo_json_methods(raw_rules_bigint=raw_rules_bigint, rule_repo=rule_repo)
diff --git a/tests/contrib/sqlalchemy/repository/sqlite/test_sqlalchemy_sqlite_uuid.py b/tests/contrib/sqlalchemy/repository/sqlite/test_sqlalchemy_sqlite_uuid.py
--- a/tests/contrib/sqlalchemy/repository/sqlite/test_sqlalchemy_sqlite_uuid.py
+++ b/tests/contrib/sqlalchemy/repository/sqlite/test_sqlalchemy_sqlite_uuid.py
@@ -8,7 +8,7 @@
 from sqlalchemy import Engine, NullPool, create_engine
 from sqlalchemy.orm import Session, sessionmaker
 
-from tests.contrib.sqlalchemy.models_uuid import AuthorSyncRepository, BookSyncRepository
+from tests.contrib.sqlalchemy.models_uuid import AuthorSyncRepository, BookSyncRepository, RuleSyncRepository
 from tests.contrib.sqlalchemy.repository import sqlalchemy_sync_uuid_tests as st
 
 pytestmark = [pytest.mark.sqlalchemy_sqlite]
@@ -34,10 +34,13 @@ def fx_engine(tmp_path: Path) -> Generator[Engine, None, None]:
 
 @pytest.fixture(name="session")
 def fx_session(
-    engine: Engine, raw_authors_uuid: list[dict[str, Any]], raw_books_uuid: list[dict[str, Any]]
+    engine: Engine,
+    raw_authors_uuid: list[dict[str, Any]],
+    raw_books_uuid: list[dict[str, Any]],
+    raw_rules_uuid: list[dict[str, Any]],
 ) -> Generator[Session, None, None]:
     session = sessionmaker(bind=engine)()
-    st.seed_db(engine, raw_authors_uuid, raw_books_uuid)
+    st.seed_db(engine, raw_authors_uuid, raw_books_uuid, raw_rules_uuid)
     try:
         yield session
     finally:
@@ -55,6 +58,11 @@ def fx_book_repo(session: Session) -> BookSyncRepository:
     return BookSyncRepository(session=session)
 
 
+@pytest.fixture(name="rule_repo")
+def fx_rule_repo(session: Session) -> RuleSyncRepository:
+    return RuleSyncRepository(session=session)
+
+
 def test_filter_by_kwargs_with_incorrect_attribute_name(author_repo: AuthorSyncRepository) -> None:
     """Test SQLALchemy filter by kwargs with invalid column name.
 
@@ -257,3 +265,16 @@ def test_repo_filter_collection(author_repo: AuthorSyncRepository) -> None:
         author_repo (AuthorRepository): The author mock repository
     """
     st.test_repo_filter_collection(author_repo=author_repo)
+
+
+def test_repo_json_methods(
+    raw_rules_uuid: list[dict[str, Any]],
+    rule_repo: RuleSyncRepository,
+) -> None:
+    """Test SQLALchemy Collection filter.
+
+    Args:
+        raw_rules_uuid (list[dict[str, Any]]): list of rules pre-seeded into the mock repository
+        rule_repo (RuleSyncRepository): The rules mock repository
+    """
+    st.test_repo_json_methods(raw_rules_uuid=raw_rules_uuid, rule_repo=rule_repo)