@martinffx/atelier 1.4.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +95 -220
  3. package/agents/architect.md +6 -6
  4. package/agents/oracle.md +1 -1
  5. package/agents/{recon.md → sentinel.md} +3 -3
  6. package/dist/atelier.js +167 -26
  7. package/package.json +2 -1
  8. package/skills/atelier-orchestrator/SKILL.md +180 -0
  9. package/skills/atelier-setup/SKILL.md +80 -0
  10. package/skills/code-review/SKILL.md +2 -2
  11. package/skills/code-review/references/reviewers.md +3 -3
  12. package/skills/code-review/references/rq.md +9 -9
  13. package/skills/code-subagents/SKILL.md +44 -75
  14. package/skills/code-subagents/references/batch-reviewer-prompt.md +44 -0
  15. package/skills/code-subagents/references/implementor-prompt.md +10 -11
  16. package/skills/spec-brainstorm/SKILL.md +21 -16
  17. package/skills/spec-finish/SKILL.md +14 -14
  18. package/skills/spec-implement/SKILL.md +42 -42
  19. package/skills/spec-plan/SKILL.md +72 -26
  20. package/skills/spec-plan/references/plan_template.md +77 -0
  21. package/skills/code-subagents/references/code-quality-reviewer-prompt.md +0 -48
  22. package/skills/code-subagents/references/spec-reviewer-prompt.md +0 -62
  23. package/skills/python-architecture/SKILL.md +0 -148
  24. package/skills/python-architecture/references/data-modeling.md +0 -558
  25. package/skills/python-architecture/references/ddd.md +0 -569
  26. package/skills/python-architecture/references/functional-core.md +0 -337
  27. package/skills/python-build-tools/SKILL.md +0 -153
  28. package/skills/python-build-tools/references/basedpyright.md +0 -321
  29. package/skills/python-build-tools/references/ruff.md +0 -225
  30. package/skills/python-build-tools/references/uv.md +0 -257
  31. package/skills/python-fastapi/SKILL.md +0 -184
  32. package/skills/python-fastapi/references/api-design.md +0 -563
  33. package/skills/python-fastapi/references/dependencies.md +0 -479
  34. package/skills/python-fastapi/references/middleware.md +0 -475
  35. package/skills/python-fastapi/references/validation.md +0 -497
  36. package/skills/python-modern-python/SKILL.md +0 -201
  37. package/skills/python-modern-python/references/async.md +0 -76
  38. package/skills/python-modern-python/references/pattern-matching.md +0 -89
  39. package/skills/python-modern-python/references/typing.md +0 -96
  40. package/skills/python-monorepo/SKILL.md +0 -146
  41. package/skills/python-monorepo/references/docker.md +0 -515
  42. package/skills/python-monorepo/references/namespace-packages.md +0 -426
  43. package/skills/python-monorepo/references/workspace-config.md +0 -341
  44. package/skills/python-sqlalchemy/SKILL.md +0 -119
  45. package/skills/python-sqlalchemy/references/async.md +0 -51
  46. package/skills/python-sqlalchemy/references/models.md +0 -67
  47. package/skills/python-sqlalchemy/references/queries.md +0 -57
  48. package/skills/python-temporal/SKILL.md +0 -128
  49. package/skills/python-temporal/references/patterns.md +0 -87
  50. package/skills/python-temporal/references/testing.md +0 -54
  51. package/skills/python-testing/SKILL.md +0 -161
  52. package/skills/python-testing/references/boundaries.md +0 -449
  53. package/skills/python-testing/references/mocking.md +0 -449
  54. package/skills/python-testing/references/pytest.md +0 -524
  55. package/skills/spec-orchestrator/SKILL.md +0 -145
  56. package/skills/typescript-api-design/SKILL.md +0 -396
  57. package/skills/typescript-api-design/references/error-responses.md +0 -469
  58. package/skills/typescript-build-tools/SKILL.md +0 -447
  59. package/skills/typescript-build-tools/references/biome.md +0 -436
  60. package/skills/typescript-build-tools/references/bun.md +0 -432
  61. package/skills/typescript-build-tools/references/turborepo.md +0 -426
  62. package/skills/typescript-build-tools/references/vitest.md +0 -518
  63. package/skills/typescript-drizzle-orm/SKILL.md +0 -398
  64. package/skills/typescript-drizzle-orm/references/cloudflare.md +0 -392
  65. package/skills/typescript-drizzle-orm/references/entity-pattern.md +0 -412
  66. package/skills/typescript-drizzle-orm/references/postgresql.md +0 -191
  67. package/skills/typescript-drizzle-orm/references/repository-pattern.md +0 -479
  68. package/skills/typescript-drizzle-orm/references/sqlite.md +0 -291
  69. package/skills/typescript-dynamodb-toolbox/SKILL.md +0 -370
  70. package/skills/typescript-dynamodb-toolbox/references/entity-layer.md +0 -574
  71. package/skills/typescript-dynamodb-toolbox/references/error-handling.md +0 -495
  72. package/skills/typescript-dynamodb-toolbox/references/modeling.md +0 -332
  73. package/skills/typescript-dynamodb-toolbox/references/repository-layer.md +0 -631
  74. package/skills/typescript-dynamodb-toolbox/references/testing.md +0 -718
  75. package/skills/typescript-dynamodb-toolbox/references/transactions.md +0 -423
  76. package/skills/typescript-effect-ts/SKILL.md +0 -341
  77. package/skills/typescript-effect-ts/references/core.md +0 -412
  78. package/skills/typescript-effect-ts/references/error-handling.md +0 -468
  79. package/skills/typescript-effect-ts/references/resources.md +0 -476
  80. package/skills/typescript-effect-ts/references/schema.md +0 -536
  81. package/skills/typescript-effect-ts/references/services.md +0 -461
  82. package/skills/typescript-fastify/SKILL.md +0 -405
  83. package/skills/typescript-fastify/references/plugins.md +0 -329
  84. package/skills/typescript-fastify/references/typeid.md +0 -315
  85. package/skills/typescript-functional-patterns/SKILL.md +0 -402
  86. package/skills/typescript-functional-patterns/references/adts.md +0 -497
  87. package/skills/typescript-functional-patterns/references/branded-types.md +0 -542
  88. package/skills/typescript-functional-patterns/references/migration-guide.md +0 -695
  89. package/skills/typescript-functional-patterns/references/option-result.md +0 -585
  90. package/skills/typescript-testing/SKILL.md +0 -353
  91. package/skills/typescript-testing/references/mocking.md +0 -675
  92. package/skills/typescript-testing/references/msw.md +0 -852
  93. package/skills/typescript-testing/references/snapshot-testing.md +0 -774
@@ -1,341 +0,0 @@
1
- # Workspace Configuration Details
2
-
3
- Comprehensive pyproject.toml patterns for Python monorepos using uv workspaces.
4
-
5
- ## Root Workspace Configuration
6
-
7
- **pyproject.toml** at repository root defines workspace structure and shared tooling:
8
-
9
- ```toml
10
- [project]
11
- name = "my-monorepo"
12
- version = "0.1.0"
13
- requires-python = ">=3.12"
14
-
15
- [tool.uv.workspace]
16
- members = [
17
- "apps/*",
18
- "packages/*"
19
- ]
20
-
21
- [tool.uv]
22
- dev-dependencies = [
23
- "pytest>=8.0.0",
24
- "ruff>=0.8.0",
25
- "basedpyright>=1.0.0",
26
- ]
27
-
28
- [tool.ruff]
29
- line-length = 100
30
- target-version = "py312"
31
-
32
- [tool.ruff.lint]
33
- select = ["E", "F", "I", "N", "UP", "RUF"]
34
-
35
- [tool.basedpyright]
36
- typeCheckingMode = "strict"
37
- ```
38
-
39
- **Key sections:**
40
- - `[project]`: Workspace metadata
41
- - `[tool.uv.workspace]`: Member glob patterns
42
- - `[tool.uv]`: Shared dev dependencies (pytest, linting, type-checking)
43
- - Tool configurations (ruff, basedpyright) shared across all packages
44
-
45
- ## Package Configuration
46
-
47
- Each workspace member has its own `pyproject.toml` with package-specific settings.
48
-
49
- ### Shared Library (packages/core)
50
-
51
- ```toml
52
- [project]
53
- name = "my-core"
54
- version = "0.1.0"
55
- requires-python = ">=3.12"
56
- description = "Shared core library"
57
- dependencies = [
58
- "pydantic>=2.0.0",
59
- ]
60
-
61
- [build-system]
62
- requires = ["hatchling"]
63
- build-backend = "hatchling.build"
64
-
65
- [tool.hatch.build.targets.wheel]
66
- packages = ["src/my_core"]
67
- ```
68
-
69
- ### Package with Dependencies (packages/utils)
70
-
71
- ```toml
72
- [project]
73
- name = "my-utils"
74
- version = "0.1.0"
75
- requires-python = ">=3.12"
76
- dependencies = [
77
- "my-core", # Reference workspace package by distribution name
78
- "python-dateutil>=2.8.0",
79
- ]
80
-
81
- [build-system]
82
- requires = ["hatchling"]
83
- build-backend = "hatchling.build"
84
-
85
- [tool.hatch.build.targets.wheel]
86
- packages = ["src/my_utils"]
87
- ```
88
-
89
- ### Application (apps/api)
90
-
91
- ```toml
92
- [project]
93
- name = "my-api"
94
- version = "0.1.0"
95
- requires-python = ">=3.12"
96
- dependencies = [
97
- "fastapi>=0.100.0",
98
- "uvicorn>=0.20.0",
99
- "my-core", # Workspace package
100
- "my-utils", # Workspace package
101
- ]
102
-
103
- [project.scripts]
104
- api = "my_api.main:run"
105
-
106
- [build-system]
107
- requires = ["hatchling"]
108
- build-backend = "hatchling.build"
109
-
110
- [tool.hatch.build.targets.wheel]
111
- packages = ["src/my_api"]
112
- ```
113
-
114
- ## Workspace Member Patterns
115
-
116
- ### Glob Pattern Variations
117
-
118
- ```toml
119
- # Include all apps and packages
120
- [tool.uv.workspace]
121
- members = ["apps/*", "packages/*"]
122
-
123
- # Include specific subdirectories
124
- [tool.uv.workspace]
125
- members = [
126
- "apps/api",
127
- "apps/worker",
128
- "packages/core",
129
- "packages/utils",
130
- ]
131
-
132
- # Namespace package pattern
133
- [tool.uv.workspace]
134
- members = ["packages/acme-*"] # All packages starting with acme-
135
- ```
136
-
137
- ### Nested Structure
138
-
139
- ```toml
140
- # For deeply nested layouts
141
- [tool.uv.workspace]
142
- members = [
143
- "services/*/service",
144
- "libs/*/library",
145
- ]
146
- ```
147
-
148
- ## Shared Tool Configuration
149
-
150
- ### Pytest Configuration
151
-
152
- ```toml
153
- [tool.pytest.ini_options]
154
- testpaths = ["packages", "apps"]
155
- python_files = ["test_*.py", "*_test.py"]
156
- python_classes = ["Test*"]
157
- python_functions = ["test_*"]
158
- addopts = "-v --strict-markers"
159
- markers = [
160
- "unit: unit tests",
161
- "integration: integration tests",
162
- "slow: slow tests",
163
- ]
164
- ```
165
-
166
- ### Ruff Configuration
167
-
168
- ```toml
169
- [tool.ruff]
170
- line-length = 100
171
- target-version = "py312"
172
-
173
- [tool.ruff.lint]
174
- select = [
175
- "E", # Errors
176
- "F", # PyFlakes
177
- "I", # isort
178
- "N", # pep8-naming
179
- "UP", # pyupgrade
180
- "RUF", # Ruff-specific
181
- ]
182
- ignore = ["E501"] # Line too long (handled by formatter)
183
-
184
- [tool.ruff.lint.isort]
185
- known-first-party = ["my_core", "my_utils", "my_api"]
186
- ```
187
-
188
- ### Type Checking (basedpyright)
189
-
190
- ```toml
191
- [tool.basedpyright]
192
- typeCheckingMode = "strict"
193
- include = ["packages/*/src", "apps/*/src"]
194
- exclude = ["**/tests", "**/__pycache__"]
195
- ```
196
-
197
- ## uv Commands
198
-
199
- ### Install and Sync
200
-
201
- ```bash
202
- # Install all workspace dependencies with lock
203
- uv sync
204
-
205
- # Sync without installing
206
- uv lock
207
-
208
- # Upgrade all dependencies
209
- uv lock --upgrade
210
-
211
- # Upgrade specific package
212
- uv lock --upgrade-package fastapi
213
- ```
214
-
215
- ### Add Dependencies
216
-
217
- ```bash
218
- # Add to root dev dependencies
219
- uv add --dev pytest
220
-
221
- # Add to specific workspace package
222
- uv add fastapi --package my-api
223
-
224
- # Add workspace package as dependency
225
- uv add my-core --package my-utils
226
-
227
- # Add with specific version
228
- uv add "requests>=2.28.0" --package my-api
229
- ```
230
-
231
- ### Run Commands
232
-
233
- ```bash
234
- # Run in root environment
235
- uv run pytest
236
-
237
- # Run in specific package
238
- uv run --package my-api pytest
239
-
240
- # Run package entrypoint
241
- uv run --package my-api api
242
-
243
- # Run Python module
244
- uv run python -m my_api.main
245
- ```
246
-
247
- ## Multi-Platform Requirements
248
-
249
- ```toml
250
- [project]
251
- dependencies = [
252
- "requests",
253
- "pywin32>=300; sys_platform == 'win32'", # Windows only
254
- "fcntl; sys_platform != 'win32'", # Unix only
255
- ]
256
- ```
257
-
258
- ## Optional Dependencies
259
-
260
- ```toml
261
- [project]
262
- name = "my-api"
263
- dependencies = ["fastapi"]
264
-
265
- [project.optional-dependencies]
266
- db = ["sqlalchemy>=2.0.0", "alembic>=1.10.0"]
267
- cache = ["redis>=4.0.0", "pydantic-settings>=2.0.0"]
268
- dev = ["pytest-cov>=4.0.0"]
269
-
270
- # Install with extras
271
- # uv sync --extra db --extra cache
272
- ```
273
-
274
- ## Version Pinning Strategies
275
-
276
- ### Loose Versioning (Recommended for libs)
277
-
278
- ```toml
279
- dependencies = [
280
- "pydantic>=2.0.0", # At least 2.0.0
281
- "requests<3", # Before 3.0.0
282
- ]
283
- ```
284
-
285
- ### Strict Versioning (For production)
286
-
287
- ```toml
288
- dependencies = [
289
- "pydantic==2.5.0", # Exact version
290
- ]
291
- ```
292
-
293
- ### Compatible Release
294
-
295
- ```toml
296
- dependencies = [
297
- "pydantic~=2.5.0", # >= 2.5.0, < 2.6.0
298
- ]
299
- ```
300
-
301
- ## Workspace with Conditional Packages
302
-
303
- ```toml
304
- [tool.uv.workspace]
305
- members = [
306
- "packages/core",
307
- "packages/postgres", # Optional database
308
- "packages/redis", # Optional cache
309
- "apps/*",
310
- ]
311
-
312
- # Then only include in dependencies when needed
313
- # my-api can depend on my-postgres when database is needed
314
- ```
315
-
316
- ## Dependency Management Best Practices
317
-
318
- 1. **Keep root dependencies minimal** - Only dev tools that apply to all packages
319
- 2. **Version independently** - Each package manages its own versions
320
- 3. **Single lock file** - One `uv.lock` at root for reproducibility
321
- 4. **Workspace references** - Use distribution names (my-core) not paths
322
- 5. **Clear boundaries** - Apps depend on packages, not vice versa
323
-
324
- ## Summary
325
-
326
- **Root config:**
327
- - Defines workspace members via glob patterns
328
- - Specifies shared dev dependencies
329
- - Centralizes tool configuration (ruff, basedpyright, pytest)
330
-
331
- **Package config:**
332
- - Independent versioning
333
- - Package-specific dependencies
334
- - Reference other workspace packages by name
335
-
336
- **Key commands:**
337
- - `uv sync` - Install all dependencies
338
- - `uv add <pkg> --package <name>` - Add to specific package
339
- - `uv lock --upgrade` - Update dependencies
340
-
341
- See `/SKILL.md` for structure overview and references for Docker and namespace packages.
@@ -1,119 +0,0 @@
1
- ---
2
- name: python-sqlalchemy
3
- description: SQLAlchemy ORM patterns for Python database access. Use when defining models, writing queries, implementing upserts, working with JSON columns, or managing database sessions.
4
- user-invocable: false
5
- ---
6
-
7
- # SQLAlchemy ORM Patterns
8
-
9
- Modern SQLAlchemy 2.0+ patterns for database access in Python applications.
10
-
11
- ## Model Definition
12
-
13
- ```python
14
- from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
15
- from sqlalchemy import String
16
- from uuid import UUID
17
- from decimal import Decimal
18
-
19
- class Base(DeclarativeBase):
20
- pass
21
-
22
- class ProductModel(Base):
23
- __tablename__ = "products"
24
-
25
- id: Mapped[UUID] = mapped_column(primary_key=True)
26
- name: Mapped[str] = mapped_column(String(100))
27
- price: Mapped[Decimal]
28
- in_stock: Mapped[bool] = mapped_column(default=True)
29
- ```
30
-
31
- ## Session Management
32
-
33
- ```python
34
- from sqlalchemy import create_engine
35
- from sqlalchemy.orm import sessionmaker
36
-
37
- engine = create_engine("postgresql://user:pass@localhost/db")
38
- SessionLocal = sessionmaker(bind=engine)
39
-
40
- def get_db():
41
- db = SessionLocal()
42
- try:
43
- yield db
44
- finally:
45
- db.close()
46
- ```
47
-
48
- ## Query Patterns
49
-
50
- ```python
51
- # Select
52
- stmt = select(ProductModel).where(ProductModel.price > 100)
53
- products = session.execute(stmt).scalars().all()
54
-
55
- # Filter
56
- products = session.query(ProductModel).filter(ProductModel.in_stock == True).all()
57
-
58
- # Get by ID
59
- product = session.get(ProductModel, product_id)
60
-
61
- # Count
62
- count = session.query(ProductModel).count()
63
- ```
64
-
65
- ## Upsert
66
-
67
- ```python
68
- from sqlalchemy.dialects.postgresql import insert
69
-
70
- stmt = insert(ProductModel).values(
71
- id=product_id,
72
- name="Widget",
73
- price=9.99,
74
- )
75
-
76
- # On conflict, update
77
- stmt = stmt.on_conflict_do_update(
78
- index_elements=["id"],
79
- set_={"name": stmt.excluded.name, "price": stmt.excluded.price},
80
- )
81
-
82
- session.execute(stmt)
83
- session.commit()
84
- ```
85
-
86
- ## Relationships
87
-
88
- ```python
89
- from sqlalchemy.orm import relationship
90
-
91
- class UserModel(Base):
92
- __tablename__ = "users"
93
- id: Mapped[int] = mapped_column(primary_key=True)
94
- orders: Mapped[list["OrderModel"]] = relationship(back_populates="user")
95
-
96
- class OrderModel(Base):
97
- __tablename__ = "orders"
98
- id: Mapped[int] = mapped_column(primary_key=True)
99
- user_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
100
- user: Mapped["UserModel"] = relationship(back_populates="orders")
101
- ```
102
-
103
- ## JSON Columns
104
-
105
- ```python
106
- from sqlalchemy import JSON
107
-
108
- class ConfigModel(Base):
109
- __tablename__ = "configs"
110
- id: Mapped[int] = mapped_column(primary_key=True)
111
- settings: Mapped[dict] = mapped_column(JSON)
112
-
113
- # Query JSON field
114
- configs = session.query(ConfigModel).filter(
115
- ConfigModel.settings["theme"] == "dark"
116
- ).all()
117
- ```
118
-
119
- See references/ for model patterns, query optimization, and async SQLAlchemy.
@@ -1,51 +0,0 @@
1
- # Async SQLAlchemy
2
-
3
- ## Setup
4
-
5
- ```python
6
- from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
7
- from sqlalchemy.ext.asyncio import async_sessionmaker
8
-
9
- engine = create_async_engine("postgresql+asyncpg://user:pass@localhost/db")
10
- AsyncSessionLocal = async_sessionmaker(engine, class_=AsyncSession)
11
-
12
- async def get_db():
13
- async with AsyncSessionLocal() as session:
14
- yield session
15
- ```
16
-
17
- ## Async Queries
18
-
19
- ```python
20
- from sqlalchemy import select
21
-
22
- async def get_users():
23
- async with AsyncSessionLocal() as session:
24
- stmt = select(User).where(User.is_active == True)
25
- result = await session.execute(stmt)
26
- return result.scalars().all()
27
-
28
- async def create_user(user_data):
29
- async with AsyncSessionLocal() as session:
30
- user = User(**user_data)
31
- session.add(user)
32
- await session.commit()
33
- await session.refresh(user)
34
- return user
35
- ```
36
-
37
- ## FastAPI Integration
38
-
39
- ```python
40
- from fastapi import Depends
41
-
42
- async def get_db():
43
- async with AsyncSessionLocal() as session:
44
- yield session
45
-
46
- @app.get("/users")
47
- async def list_users(db: AsyncSession = Depends(get_db)):
48
- stmt = select(User)
49
- result = await db.execute(stmt)
50
- return result.scalars().all()
51
- ```
@@ -1,67 +0,0 @@
1
- # SQLAlchemy Models
2
-
3
- ## Declarative Models (2.0 Style)
4
-
5
- ```python
6
- from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
7
- from sqlalchemy import String, ForeignKey
8
- from datetime import datetime
9
- from uuid import UUID
10
-
11
- class Base(DeclarativeBase):
12
- pass
13
-
14
- class User(Base):
15
- __tablename__ = "users"
16
-
17
- id: Mapped[int] = mapped_column(primary_key=True)
18
- email: Mapped[str] = mapped_column(String(255), unique=True)
19
- name: Mapped[str] = mapped_column(String(100))
20
- created_at: Mapped[datetime] = mapped_column(default=datetime.now)
21
- is_active: Mapped[bool] = mapped_column(default=True)
22
- ```
23
-
24
- ## Relationships
25
-
26
- ```python
27
- from sqlalchemy.orm import relationship
28
-
29
- class User(Base):
30
- __tablename__ = "users"
31
- id: Mapped[int] = mapped_column(primary_key=True)
32
- orders: Mapped[list["Order"]] = relationship(back_populates="user")
33
-
34
- class Order(Base):
35
- __tablename__ = "orders"
36
- id: Mapped[int] = mapped_column(primary_key=True)
37
- user_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
38
- user: Mapped["User"] = relationship(back_populates="orders")
39
- ```
40
-
41
- ## Indexes
42
-
43
- ```python
44
- from sqlalchemy import Index
45
-
46
- class Product(Base):
47
- __tablename__ = "products"
48
-
49
- id: Mapped[int] = mapped_column(primary_key=True)
50
- category: Mapped[str]
51
- price: Mapped[Decimal]
52
-
53
- __table_args__ = (
54
- Index("idx_category_price", "category", "price"),
55
- )
56
- ```
57
-
58
- ## JSON Columns
59
-
60
- ```python
61
- from sqlalchemy import JSON
62
-
63
- class Config(Base):
64
- __tablename__ = "configs"
65
- id: Mapped[int] = mapped_column(primary_key=True)
66
- settings: Mapped[dict] = mapped_column(JSON)
67
- ```
@@ -1,57 +0,0 @@
1
- # SQLAlchemy Queries
2
-
3
- ## Select Queries (2.0 Style)
4
-
5
- ```python
6
- from sqlalchemy import select
7
-
8
- # All records
9
- stmt = select(User)
10
- users = session.execute(stmt).scalars().all()
11
-
12
- # With filter
13
- stmt = select(User).where(User.is_active == True)
14
- users = session.execute(stmt).scalars().all()
15
-
16
- # Get one
17
- stmt = select(User).where(User.id == 1)
18
- user = session.execute(stmt).scalar_one()
19
-
20
- # Get by ID
21
- user = session.get(User, 1)
22
- ```
23
-
24
- ## Joins
25
-
26
- ```python
27
- stmt = select(User, Order).join(Order, User.id == Order.user_id)
28
- results = session.execute(stmt).all()
29
-
30
- # With filter
31
- stmt = select(User).join(User.orders).where(Order.total > 100)
32
- users = session.execute(stmt).scalars().all()
33
- ```
34
-
35
- ## Aggregation
36
-
37
- ```python
38
- from sqlalchemy import func
39
-
40
- # Count
41
- count = session.query(User).count()
42
-
43
- # Sum
44
- total = session.query(func.sum(Order.total)).scalar()
45
-
46
- # Group by
47
- stmt = select(User.id, func.count(Order.id)).join(Order).group_by(User.id)
48
- results = session.execute(stmt).all()
49
- ```
50
-
51
- ## Pagination
52
-
53
- ```python
54
- # Offset/limit
55
- stmt = select(User).offset(skip).limit(limit)
56
- users = session.execute(stmt).scalars().all()
57
- ```