Skip to content

Commit 5afa40f

Browse files
JorenSixcofinpeterschutt
authored
docs: SQLAlchemyInitPlugin to SQLAlchemyPlugin fixes SerializationException for docs (#3475)
* Update sqlalchemy_declarative_models.py Now uses the SQLAlchemyPlugin in stead of SQLAlchemyInitPlugin, see #3464 * Update sqlalchemy_declarative_models.py Ruff lint fixes * Update docs/examples/contrib/sqlalchemy/sqlalchemy_declarative_models.py create_all flag Co-authored-by: Cody Fincher <[email protected]> * Update docs/examples/contrib/sqlalchemy/sqlalchemy_declarative_models.py Co-authored-by: Peter Schutt <[email protected]> * Update docs/examples/contrib/sqlalchemy/sqlalchemy_declarative_models.py Further documentation Co-authored-by: Peter Schutt <[email protected]> * Update docs/examples/contrib/sqlalchemy/sqlalchemy_declarative_models.py Co-authored-by: Peter Schutt <[email protected]> * Update docs/examples/contrib/sqlalchemy/sqlalchemy_declarative_models.py Co-authored-by: Cody Fincher <[email protected]> * Unit test for sqlalchemy_declarative_models. * Now using option create_all=True for meta-data, on_startup for dummy data * Lint ruff-format compatibility * Fix for 3.9 and 3.10 wrt class declarations/typing * Ruff format check * Removed comments which might be heavy for example code * For 3.8 compatibility wrt typing now using List in stead of list * Replaced incorrect use of List instead of List --------- Co-authored-by: Cody Fincher <[email protected]> Co-authored-by: Peter Schutt <[email protected]>
1 parent 142bfe3 commit 5afa40f

File tree

3 files changed

+36
-14
lines changed

3 files changed

+36
-14
lines changed
Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
1+
from __future__ import annotations
2+
3+
import uuid
14
from datetime import date
2-
from typing import TYPE_CHECKING
5+
from typing import List
36
from uuid import UUID
47

5-
from sqlalchemy import ForeignKey, select
8+
from sqlalchemy import ForeignKey, func, select
9+
from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession
610
from sqlalchemy.orm import Mapped, mapped_column, relationship
711

812
from litestar import Litestar, get
913
from litestar.contrib.sqlalchemy.base import UUIDAuditBase, UUIDBase
10-
from litestar.contrib.sqlalchemy.plugins import AsyncSessionConfig, SQLAlchemyAsyncConfig, SQLAlchemyInitPlugin
11-
12-
if TYPE_CHECKING:
13-
from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession
14+
from litestar.contrib.sqlalchemy.plugins import AsyncSessionConfig, SQLAlchemyAsyncConfig, SQLAlchemyPlugin
1415

1516

1617
# the SQLAlchemy base includes a declarative model for you to use in your models.
1718
# The `Base` class includes a `UUID` based primary key (`id`)
1819
class Author(UUIDBase):
1920
name: Mapped[str]
2021
dob: Mapped[date]
21-
books: Mapped[list["Book"]] = relationship(back_populates="author", lazy="selectin")
22+
books: Mapped[List[Book]] = relationship(back_populates="author", lazy="selectin")
2223

2324

2425
# The `AuditBase` class includes the same UUID` based primary key (`id`) and 2
@@ -32,25 +33,31 @@ class Book(UUIDAuditBase):
3233

3334
session_config = AsyncSessionConfig(expire_on_commit=False)
3435
sqlalchemy_config = SQLAlchemyAsyncConfig(
35-
connection_string="sqlite+aiosqlite:///test.sqlite", session_config=session_config
36+
connection_string="sqlite+aiosqlite:///test.sqlite", session_config=session_config, create_all=True
3637
) # Create 'async_session' dependency.
37-
sqlalchemy_plugin = SQLAlchemyInitPlugin(config=sqlalchemy_config)
3838

3939

4040
async def on_startup() -> None:
41-
"""Initializes the database."""
42-
async with sqlalchemy_config.get_engine().begin() as conn:
43-
await conn.run_sync(UUIDBase.metadata.create_all)
41+
"""Adds some dummy data if no data is present."""
42+
async with sqlalchemy_config.get_session() as session:
43+
statement = select(func.count()).select_from(Author)
44+
count = await session.execute(statement)
45+
if not count.scalar():
46+
author_id = uuid.uuid4()
47+
session.add(Author(name="Stephen King", dob=date(1954, 9, 21), id=author_id))
48+
session.add(Book(title="It", author_id=author_id))
49+
await session.commit()
4450

4551

4652
@get(path="/authors")
47-
async def get_authors(db_session: "AsyncSession", db_engine: "AsyncEngine") -> list[Author]:
53+
async def get_authors(db_session: AsyncSession, db_engine: AsyncEngine) -> List[Author]:
4854
"""Interact with SQLAlchemy engine and session."""
4955
return list(await db_session.scalars(select(Author)))
5056

5157

5258
app = Litestar(
5359
route_handlers=[get_authors],
5460
on_startup=[on_startup],
55-
plugins=[SQLAlchemyInitPlugin(config=sqlalchemy_config)],
61+
debug=True,
62+
plugins=[SQLAlchemyPlugin(config=sqlalchemy_config)],
5663
)

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ known-first-party = ["litestar", "tests", "examples"]
395395
"docs/examples/application_hooks/before_send_hook.py" = ["UP006"]
396396
"docs/examples/contrib/sqlalchemy/plugins/**/*.*" = ["UP006"]
397397
"docs/examples/data_transfer_objects**/*.*" = ["UP006"]
398+
"docs/examples/contrib/sqlalchemy/sqlalchemy_declarative_models.py" = ["UP006"]
398399
"litestar/_openapi/schema_generation/schema.py" = ["C901"]
399400
"litestar/exceptions/*.*" = ["N818"]
400401
"litestar/handlers/**/*.*" = ["N801"]
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import pytest
2+
3+
from litestar.testing import TestClient
4+
5+
pytestmark = pytest.mark.xdist_group("sqlalchemy_examples")
6+
7+
8+
def test_sqlalchemy_declarative_models() -> None:
9+
from docs.examples.contrib.sqlalchemy.sqlalchemy_declarative_models import app
10+
11+
with TestClient(app) as client:
12+
response = client.get("/authors")
13+
assert response.status_code == 200
14+
assert len(response.json()) > 0

0 commit comments

Comments
 (0)