varco-sa 0.0.1__tar.gz
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.
- varco_sa-0.0.1/PKG-INFO +191 -0
- varco_sa-0.0.1/README.md +163 -0
- varco_sa-0.0.1/pyproject.toml +49 -0
- varco_sa-0.0.1/varco_sa/__init__.py +78 -0
- varco_sa-0.0.1/varco_sa/alembic_helpers.py +233 -0
- varco_sa-0.0.1/varco_sa/bootstrap.py +259 -0
- varco_sa-0.0.1/varco_sa/factory.py +389 -0
- varco_sa-0.0.1/varco_sa/models.py +78 -0
- varco_sa-0.0.1/varco_sa/provider.py +115 -0
- varco_sa-0.0.1/varco_sa/repository.py +343 -0
- varco_sa-0.0.1/varco_sa/schema_guard.py +348 -0
- varco_sa-0.0.1/varco_sa/sqlalchemy_session.py +51 -0
- varco_sa-0.0.1/varco_sa/type_coercion.py +71 -0
- varco_sa-0.0.1/varco_sa/uow.py +70 -0
varco_sa-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: varco-sa
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: SQLAlchemy async backend for varco — runtime ORM generation, repository, schema guard, and Alembic helpers
|
|
5
|
+
License: Apache-2.0
|
|
6
|
+
Keywords: fastapi,sqlalchemy,async,domain-model,repository,alembic,orm,schema-guard
|
|
7
|
+
Author: edoardo.scarpaci
|
|
8
|
+
Author-email: edoardo.scarpaci@gmail.com
|
|
9
|
+
Requires-Python: >=3.12
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Framework :: FastAPI
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Classifier: Topic :: Database
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
20
|
+
Classifier: Typing :: Typed
|
|
21
|
+
Requires-Dist: sqlalchemy[asyncio] (>=2.0)
|
|
22
|
+
Requires-Dist: varco-core (>=0.0.1)
|
|
23
|
+
Project-URL: Documentation, https://github.com/edoardoscarpaci/varco#sqlalchemy-backend
|
|
24
|
+
Project-URL: Homepage, https://github.com/edoardoscarpaci/varco
|
|
25
|
+
Project-URL: Repository, https://github.com/edoardoscarpaci/varco
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
|
|
28
|
+
# varco-sa
|
|
29
|
+
|
|
30
|
+
[](https://pypi.org/project/varco-sa/)
|
|
31
|
+
[](https://pypi.org/project/varco-sa/)
|
|
32
|
+
[](https://github.com/edoardoscarpaci/varco/blob/main/LICENSE)
|
|
33
|
+
[](https://github.com/edoardoscarpaci/varco)
|
|
34
|
+
|
|
35
|
+
SQLAlchemy async backend for **varco**.
|
|
36
|
+
|
|
37
|
+
Generates SQLAlchemy ORM classes at runtime from your `DomainModel` subclasses — no hand-written ORM models needed. Requires [`varco-core`](https://pypi.org/project/varco-core/).
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Install
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pip install varco-sa
|
|
45
|
+
|
|
46
|
+
# With PostgreSQL async driver:
|
|
47
|
+
pip install "varco-sa[postgresql]"
|
|
48
|
+
|
|
49
|
+
# With SQLite (tests / local dev):
|
|
50
|
+
pip install "varco-sa[sqlite]"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Features
|
|
56
|
+
|
|
57
|
+
- **Zero-boilerplate ORM** — `SAModelFactory` generates `DeclarativeBase` subclasses at runtime; no duplication between domain and ORM layers
|
|
58
|
+
- **Full async repository** — `AsyncSQLAlchemyRepository` implements `AsyncRepository` (CRUD, `exists()`, `stream_by_query()` with server-side cursor)
|
|
59
|
+
- **Unit of Work** — `SQLAlchemyUnitOfWork` manages `AsyncSession` lifecycle and atomic commits
|
|
60
|
+
- **One-liner bootstrap** — `SAFastrestApp` + `SAConfig` wire engine, session factory, ORM generation, and table creation
|
|
61
|
+
- **Alembic integration** — `get_target_metadata()` and `print_create_ddl()` helpers for migration scripts
|
|
62
|
+
- **Schema Guard** — `SchemaGuard` detects drift between ORM metadata and the live database schema
|
|
63
|
+
- **Query integration** — accepts `varco-core` `QueryParams` / `QueryBuilder` AST natively; translates to SQLAlchemy `where()` clauses
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## What's in the package
|
|
68
|
+
|
|
69
|
+
| Module | Purpose |
|
|
70
|
+
|---|---|
|
|
71
|
+
| `factory.py` | `SAModelFactory` — generates `DeclarativeBase` subclasses at runtime; `SAModelRegistry` — escape hatch |
|
|
72
|
+
| `repository.py` | `AsyncSQLAlchemyRepository` — `AsyncSession`-backed CRUD + `exists()` + `stream_by_query()` |
|
|
73
|
+
| `uow.py` | `SQLAlchemyUnitOfWork` — session lifecycle + atomic commits |
|
|
74
|
+
| `provider.py` | `SQLAlchemyRepositoryProvider` — wires factory + repos + UoW |
|
|
75
|
+
| `bootstrap.py` | `SAConfig`, `SAFastrestApp` — one-liner app setup |
|
|
76
|
+
| `alembic_helpers.py` | `get_target_metadata`, `print_create_ddl` — Alembic integration |
|
|
77
|
+
| `schema_guard.py` | `SchemaGuard` — drift detection between ORM metadata and live DB |
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Quick start
|
|
82
|
+
|
|
83
|
+
### Bootstrap (one-liner)
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from sqlalchemy.ext.asyncio import create_async_engine
|
|
87
|
+
from sqlalchemy.orm import DeclarativeBase
|
|
88
|
+
from varco_sa import SAConfig, SAFastrestApp
|
|
89
|
+
|
|
90
|
+
class Base(DeclarativeBase): pass
|
|
91
|
+
|
|
92
|
+
engine = create_async_engine("postgresql+asyncpg://user:pass@localhost/mydb")
|
|
93
|
+
|
|
94
|
+
app = SAFastrestApp(SAConfig(
|
|
95
|
+
engine=engine,
|
|
96
|
+
base=Base,
|
|
97
|
+
entity_classes=(User, Post),
|
|
98
|
+
))
|
|
99
|
+
|
|
100
|
+
await app.create_all() # CREATE TABLE IF NOT EXISTS ...
|
|
101
|
+
uow_provider = app.uow_provider # ready to inject as IUoWProvider
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Manual setup
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
from sqlalchemy.ext.asyncio import async_sessionmaker
|
|
108
|
+
from varco_sa import SQLAlchemyRepositoryProvider
|
|
109
|
+
|
|
110
|
+
sessions = async_sessionmaker(engine, expire_on_commit=False)
|
|
111
|
+
provider = SQLAlchemyRepositoryProvider(engine=engine, session_factory=sessions)
|
|
112
|
+
provider.register(User, Post)
|
|
113
|
+
await provider.create_all()
|
|
114
|
+
|
|
115
|
+
async with provider.make_uow() as uow:
|
|
116
|
+
user = await uow.users.save(User(name="Edo", email="edo@example.com"))
|
|
117
|
+
print(user.pk)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Query integration
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
from varco_core import QueryBuilder, QueryParams
|
|
124
|
+
|
|
125
|
+
async with provider.make_uow() as uow:
|
|
126
|
+
# exists() — uses SA identity-map cache, no full ORM load when cached
|
|
127
|
+
if await uow.posts.exists(post_id):
|
|
128
|
+
...
|
|
129
|
+
|
|
130
|
+
# stream_by_query() — server-side cursor, constant memory regardless of result size
|
|
131
|
+
params = QueryParams(node=QueryBuilder().eq("active", True).build())
|
|
132
|
+
async for post in uow.posts.stream_by_query(params):
|
|
133
|
+
await process(post)
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Alembic integration
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
# alembic/env.py
|
|
140
|
+
from varco_sa import get_target_metadata
|
|
141
|
+
from myapp.models import User, Post
|
|
142
|
+
|
|
143
|
+
target_metadata = get_target_metadata(User, Post)
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Preview the DDL before running a migration:
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
from varco_sa import print_create_ddl
|
|
150
|
+
|
|
151
|
+
print(print_create_ddl(User, Post, dialect="postgresql"))
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Schema Guard — detect drift
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
from varco_sa import SchemaGuard
|
|
158
|
+
|
|
159
|
+
guard = SchemaGuard(engine, User, Post)
|
|
160
|
+
differences = await guard.check()
|
|
161
|
+
if differences:
|
|
162
|
+
print("Schema drift detected:", differences)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Access the generated SA model (escape hatch)
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
from varco_sa import SAModelRegistry
|
|
169
|
+
from sqlalchemy.orm import relationship
|
|
170
|
+
|
|
171
|
+
UserORM = SAModelRegistry.get(User)
|
|
172
|
+
UserORM.posts = relationship("PostORM", back_populates="author")
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Related packages
|
|
178
|
+
|
|
179
|
+
| Package | Description |
|
|
180
|
+
|---|---|
|
|
181
|
+
| [`varco-core`](https://pypi.org/project/varco-core/) | Domain model, service layer, query AST, JWT — required dependency |
|
|
182
|
+
| [`varco-beanie`](https://pypi.org/project/varco-beanie/) | Beanie / Motor MongoDB backend (alternative to this package) |
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Links
|
|
187
|
+
|
|
188
|
+
- **Repository**: https://github.com/edoardoscarpaci/varco
|
|
189
|
+
- **Full docs**: https://github.com/edoardoscarpaci/varco#sqlalchemy-backend
|
|
190
|
+
- **Issue tracker**: https://github.com/edoardoscarpaci/varco/issues
|
|
191
|
+
|
varco_sa-0.0.1/README.md
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# varco-sa
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/varco-sa/)
|
|
4
|
+
[](https://pypi.org/project/varco-sa/)
|
|
5
|
+
[](https://github.com/edoardoscarpaci/varco/blob/main/LICENSE)
|
|
6
|
+
[](https://github.com/edoardoscarpaci/varco)
|
|
7
|
+
|
|
8
|
+
SQLAlchemy async backend for **varco**.
|
|
9
|
+
|
|
10
|
+
Generates SQLAlchemy ORM classes at runtime from your `DomainModel` subclasses — no hand-written ORM models needed. Requires [`varco-core`](https://pypi.org/project/varco-core/).
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install varco-sa
|
|
18
|
+
|
|
19
|
+
# With PostgreSQL async driver:
|
|
20
|
+
pip install "varco-sa[postgresql]"
|
|
21
|
+
|
|
22
|
+
# With SQLite (tests / local dev):
|
|
23
|
+
pip install "varco-sa[sqlite]"
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Features
|
|
29
|
+
|
|
30
|
+
- **Zero-boilerplate ORM** — `SAModelFactory` generates `DeclarativeBase` subclasses at runtime; no duplication between domain and ORM layers
|
|
31
|
+
- **Full async repository** — `AsyncSQLAlchemyRepository` implements `AsyncRepository` (CRUD, `exists()`, `stream_by_query()` with server-side cursor)
|
|
32
|
+
- **Unit of Work** — `SQLAlchemyUnitOfWork` manages `AsyncSession` lifecycle and atomic commits
|
|
33
|
+
- **One-liner bootstrap** — `SAFastrestApp` + `SAConfig` wire engine, session factory, ORM generation, and table creation
|
|
34
|
+
- **Alembic integration** — `get_target_metadata()` and `print_create_ddl()` helpers for migration scripts
|
|
35
|
+
- **Schema Guard** — `SchemaGuard` detects drift between ORM metadata and the live database schema
|
|
36
|
+
- **Query integration** — accepts `varco-core` `QueryParams` / `QueryBuilder` AST natively; translates to SQLAlchemy `where()` clauses
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## What's in the package
|
|
41
|
+
|
|
42
|
+
| Module | Purpose |
|
|
43
|
+
|---|---|
|
|
44
|
+
| `factory.py` | `SAModelFactory` — generates `DeclarativeBase` subclasses at runtime; `SAModelRegistry` — escape hatch |
|
|
45
|
+
| `repository.py` | `AsyncSQLAlchemyRepository` — `AsyncSession`-backed CRUD + `exists()` + `stream_by_query()` |
|
|
46
|
+
| `uow.py` | `SQLAlchemyUnitOfWork` — session lifecycle + atomic commits |
|
|
47
|
+
| `provider.py` | `SQLAlchemyRepositoryProvider` — wires factory + repos + UoW |
|
|
48
|
+
| `bootstrap.py` | `SAConfig`, `SAFastrestApp` — one-liner app setup |
|
|
49
|
+
| `alembic_helpers.py` | `get_target_metadata`, `print_create_ddl` — Alembic integration |
|
|
50
|
+
| `schema_guard.py` | `SchemaGuard` — drift detection between ORM metadata and live DB |
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Quick start
|
|
55
|
+
|
|
56
|
+
### Bootstrap (one-liner)
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
from sqlalchemy.ext.asyncio import create_async_engine
|
|
60
|
+
from sqlalchemy.orm import DeclarativeBase
|
|
61
|
+
from varco_sa import SAConfig, SAFastrestApp
|
|
62
|
+
|
|
63
|
+
class Base(DeclarativeBase): pass
|
|
64
|
+
|
|
65
|
+
engine = create_async_engine("postgresql+asyncpg://user:pass@localhost/mydb")
|
|
66
|
+
|
|
67
|
+
app = SAFastrestApp(SAConfig(
|
|
68
|
+
engine=engine,
|
|
69
|
+
base=Base,
|
|
70
|
+
entity_classes=(User, Post),
|
|
71
|
+
))
|
|
72
|
+
|
|
73
|
+
await app.create_all() # CREATE TABLE IF NOT EXISTS ...
|
|
74
|
+
uow_provider = app.uow_provider # ready to inject as IUoWProvider
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Manual setup
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
from sqlalchemy.ext.asyncio import async_sessionmaker
|
|
81
|
+
from varco_sa import SQLAlchemyRepositoryProvider
|
|
82
|
+
|
|
83
|
+
sessions = async_sessionmaker(engine, expire_on_commit=False)
|
|
84
|
+
provider = SQLAlchemyRepositoryProvider(engine=engine, session_factory=sessions)
|
|
85
|
+
provider.register(User, Post)
|
|
86
|
+
await provider.create_all()
|
|
87
|
+
|
|
88
|
+
async with provider.make_uow() as uow:
|
|
89
|
+
user = await uow.users.save(User(name="Edo", email="edo@example.com"))
|
|
90
|
+
print(user.pk)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Query integration
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
from varco_core import QueryBuilder, QueryParams
|
|
97
|
+
|
|
98
|
+
async with provider.make_uow() as uow:
|
|
99
|
+
# exists() — uses SA identity-map cache, no full ORM load when cached
|
|
100
|
+
if await uow.posts.exists(post_id):
|
|
101
|
+
...
|
|
102
|
+
|
|
103
|
+
# stream_by_query() — server-side cursor, constant memory regardless of result size
|
|
104
|
+
params = QueryParams(node=QueryBuilder().eq("active", True).build())
|
|
105
|
+
async for post in uow.posts.stream_by_query(params):
|
|
106
|
+
await process(post)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Alembic integration
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
# alembic/env.py
|
|
113
|
+
from varco_sa import get_target_metadata
|
|
114
|
+
from myapp.models import User, Post
|
|
115
|
+
|
|
116
|
+
target_metadata = get_target_metadata(User, Post)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Preview the DDL before running a migration:
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
from varco_sa import print_create_ddl
|
|
123
|
+
|
|
124
|
+
print(print_create_ddl(User, Post, dialect="postgresql"))
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Schema Guard — detect drift
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
from varco_sa import SchemaGuard
|
|
131
|
+
|
|
132
|
+
guard = SchemaGuard(engine, User, Post)
|
|
133
|
+
differences = await guard.check()
|
|
134
|
+
if differences:
|
|
135
|
+
print("Schema drift detected:", differences)
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Access the generated SA model (escape hatch)
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
from varco_sa import SAModelRegistry
|
|
142
|
+
from sqlalchemy.orm import relationship
|
|
143
|
+
|
|
144
|
+
UserORM = SAModelRegistry.get(User)
|
|
145
|
+
UserORM.posts = relationship("PostORM", back_populates="author")
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Related packages
|
|
151
|
+
|
|
152
|
+
| Package | Description |
|
|
153
|
+
|---|---|
|
|
154
|
+
| [`varco-core`](https://pypi.org/project/varco-core/) | Domain model, service layer, query AST, JWT — required dependency |
|
|
155
|
+
| [`varco-beanie`](https://pypi.org/project/varco-beanie/) | Beanie / Motor MongoDB backend (alternative to this package) |
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Links
|
|
160
|
+
|
|
161
|
+
- **Repository**: https://github.com/edoardoscarpaci/varco
|
|
162
|
+
- **Full docs**: https://github.com/edoardoscarpaci/varco#sqlalchemy-backend
|
|
163
|
+
- **Issue tracker**: https://github.com/edoardoscarpaci/varco/issues
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
name = "varco-sa"
|
|
3
|
+
version = "0.0.1"
|
|
4
|
+
description = "SQLAlchemy async backend for varco — runtime ORM generation, repository, schema guard, and Alembic helpers"
|
|
5
|
+
authors = ["edoardo.scarpaci <edoardo.scarpaci@gmail.com>"]
|
|
6
|
+
readme = "README.md"
|
|
7
|
+
license = "Apache-2.0"
|
|
8
|
+
homepage = "https://github.com/edoardoscarpaci/varco"
|
|
9
|
+
repository = "https://github.com/edoardoscarpaci/varco"
|
|
10
|
+
documentation = "https://github.com/edoardoscarpaci/varco#sqlalchemy-backend"
|
|
11
|
+
keywords = ["fastapi", "sqlalchemy", "async", "domain-model", "repository", "alembic", "orm", "schema-guard"]
|
|
12
|
+
classifiers = [
|
|
13
|
+
"Development Status :: 3 - Alpha",
|
|
14
|
+
"Intended Audience :: Developers",
|
|
15
|
+
"License :: OSI Approved :: Apache Software License",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3.12",
|
|
18
|
+
"Topic :: Software Development :: Libraries :: Application Frameworks",
|
|
19
|
+
"Topic :: Database",
|
|
20
|
+
"Framework :: FastAPI",
|
|
21
|
+
"Typing :: Typed",
|
|
22
|
+
]
|
|
23
|
+
packages = [{include = "varco_sa"}]
|
|
24
|
+
|
|
25
|
+
[tool.poetry.dependencies]
|
|
26
|
+
python = ">=3.12"
|
|
27
|
+
# Path dependency — installs varco_core in editable mode from the monorepo.
|
|
28
|
+
# Changes to varco_core are immediately visible without reinstalling.
|
|
29
|
+
varco-core = ">=0.0.1"
|
|
30
|
+
sqlalchemy = {version = ">=2.0", extras = ["asyncio"]}
|
|
31
|
+
|
|
32
|
+
[tool.poetry.group.postgresql.dependencies]
|
|
33
|
+
# Install with: poetry install --with postgresql
|
|
34
|
+
asyncpg = ">=0.29"
|
|
35
|
+
|
|
36
|
+
[tool.poetry.group.dev.dependencies]
|
|
37
|
+
# aiosqlite is included here (not just sqlite group) so tests run without
|
|
38
|
+
# needing a separate --with sqlite flag during local development.
|
|
39
|
+
pytest = ">=8.0"
|
|
40
|
+
pytest-asyncio = ">=0.24"
|
|
41
|
+
aiosqlite = ">=0.20"
|
|
42
|
+
|
|
43
|
+
[build-system]
|
|
44
|
+
requires = ["poetry-core>=2.0.0,<3.0.0", "poetry-monorepo-dependency-plugin"]
|
|
45
|
+
build-backend = "poetry.core.masonry.api"
|
|
46
|
+
|
|
47
|
+
[tool.pytest.ini_options]
|
|
48
|
+
asyncio_mode = "auto"
|
|
49
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"""
|
|
2
|
+
varco_sa
|
|
3
|
+
============
|
|
4
|
+
SQLAlchemy async backend for varco.
|
|
5
|
+
|
|
6
|
+
All stable public symbols are importable directly from ``varco_sa``::
|
|
7
|
+
|
|
8
|
+
from varco_sa import SQLAlchemyRepositoryProvider, SAModelRegistry
|
|
9
|
+
from varco_sa import BaseDatabaseModel, IndexedDatabaseModel
|
|
10
|
+
from varco_sa import SQLAlchemyQueryApplicator
|
|
11
|
+
|
|
12
|
+
# Query usage
|
|
13
|
+
from varco_core import QueryBuilder, QueryParams
|
|
14
|
+
from varco_sa import SQLAlchemyRepositoryProvider
|
|
15
|
+
|
|
16
|
+
provider = SQLAlchemyRepositoryProvider(base=Base, session_factory=async_session)
|
|
17
|
+
provider.register(User, Post)
|
|
18
|
+
|
|
19
|
+
async with provider.make_uow() as uow:
|
|
20
|
+
active_users = await uow.users.find_by_query(
|
|
21
|
+
QueryParams(
|
|
22
|
+
node=QueryBuilder().eq("active", True).build(),
|
|
23
|
+
limit=20,
|
|
24
|
+
)
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
Sub-package layout
|
|
28
|
+
------------------
|
|
29
|
+
varco_sa/
|
|
30
|
+
├── factory.py — SAModelFactory (DomainModel → SA ORM class at runtime)
|
|
31
|
+
│ SAModelRegistry (process-level ORM class registry)
|
|
32
|
+
├── provider.py — SQLAlchemyRepositoryProvider
|
|
33
|
+
├── repository.py — AsyncSQLAlchemyRepository (CRUD + find_by_query + count)
|
|
34
|
+
├── uow.py — SQLAlchemyUnitOfWork
|
|
35
|
+
└── models.py — BaseDatabaseModel
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
from __future__ import annotations
|
|
39
|
+
|
|
40
|
+
from varco_sa.alembic_helpers import get_target_metadata, print_create_ddl
|
|
41
|
+
from varco_sa.bootstrap import SAConfig, SAFastrestApp
|
|
42
|
+
from varco_sa.factory import SAModelFactory, SAModelRegistry
|
|
43
|
+
from varco_sa.models import BaseDatabaseModel
|
|
44
|
+
from varco_sa.provider import SQLAlchemyRepositoryProvider
|
|
45
|
+
from varco_sa.repository import AsyncSQLAlchemyRepository
|
|
46
|
+
from varco_sa.schema_guard import SchemaGuard, SchemaDrift, SchemaDriftReport
|
|
47
|
+
from varco_sa.uow import SQLAlchemyUnitOfWork
|
|
48
|
+
|
|
49
|
+
# SA-specific applicator is in varco_core (no session; pure SA expressions)
|
|
50
|
+
from varco_core.query.applicator.sqlalchemy import SQLAlchemyQueryApplicator
|
|
51
|
+
from varco_sa.type_coercion import registry_from_sa_model
|
|
52
|
+
|
|
53
|
+
__all__ = [
|
|
54
|
+
# ── Factory + registry ─────────────────────────────────────────────────────
|
|
55
|
+
"SAModelFactory",
|
|
56
|
+
"SAModelRegistry",
|
|
57
|
+
# ── Repository + UoW ──────────────────────────────────────────────────────
|
|
58
|
+
"AsyncSQLAlchemyRepository",
|
|
59
|
+
"SQLAlchemyUnitOfWork",
|
|
60
|
+
# ── Provider ──────────────────────────────────────────────────────────────
|
|
61
|
+
"SQLAlchemyRepositoryProvider",
|
|
62
|
+
# ── Base models ───────────────────────────────────────────────────────────
|
|
63
|
+
"BaseDatabaseModel",
|
|
64
|
+
# ── Query applicator ──────────────────────────────────────────────────────
|
|
65
|
+
"SQLAlchemyQueryApplicator",
|
|
66
|
+
# ── Schema guard ──────────────────────────────────────────────────────────
|
|
67
|
+
"SchemaGuard",
|
|
68
|
+
"SchemaDrift",
|
|
69
|
+
"SchemaDriftReport",
|
|
70
|
+
# ── Type coercion ─────────────────────────────────────────────────────────
|
|
71
|
+
"registry_from_sa_model",
|
|
72
|
+
# ── Alembic helpers ───────────────────────────────────────────────────────
|
|
73
|
+
"get_target_metadata",
|
|
74
|
+
"print_create_ddl",
|
|
75
|
+
# ── Bootstrap ─────────────────────────────────────────────────────────────
|
|
76
|
+
"SAConfig",
|
|
77
|
+
"SAFastrestApp",
|
|
78
|
+
]
|