Skip to content

Commit e81da85

Browse files
committed
Added support for Table, refactored model creation and added tests
1 parent d4f9f83 commit e81da85

39 files changed

+2396
-240
lines changed

.github/workflows/publish.yml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@ jobs:
1818
run: pip install flit
1919
- name: Install Dependencies
2020
run: flit install --symlink
21+
- name: Install build dependencies
22+
run: pip install build
23+
- name: Build distribution
24+
run: python -m build
2125
- name: Publish
22-
env:
23-
FLIT_USERNAME: ${{ secrets.FLIT_USERNAME }}
24-
FLIT_PASSWORD: ${{ secrets.FLIT_PASSWORD }}
25-
run: flit publish
26+
uses: pypa/gh-action-pypi-publish@v1.8.10
27+
with:
28+
password: ${{ secrets.FLIT_PASSWORD }}

README.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,20 @@
99
[![PyPI version](https://img.shields.io/pypi/pyversions/ellar-sqlachemy.svg)](https://pypi.python.org/pypi/ellar-sqlachemy)
1010

1111
## Project Status
12-
- 70% done
13-
- Tests
14-
- Documentation
12+
[] Overall Completion - 80% done
13+
[] Tests - 90% Complete
14+
[x] Model class to create SQLAlchemy Models and Declarative Base
15+
[x] SQLAlchemy model export to dictionary through `model.dict(exclude={'x', 'y', 'z'})`
16+
[x] Support multiple database configuration in Models and in Query
17+
[x] Session to manage Model metadata
18+
[x] Service to manage Engine and Session creation and Migration initialization for async and sync Engines and Sessions
19+
[x] Alembic env.py with async first `run_migrations_online` action
20+
[x] Expose all alembic commands to Ellar CLI
21+
[x] Module to config and setup SQLAlchemy dependencies and migration
22+
[] SQLAlchemy Pagination for both templating and api routes
23+
[x] File and Image SQLAlchemy Columns integrated with ellar storage
24+
[] SQLAlchemy Django Like Query
25+
[] Documentation
1526

1627
## Introduction
1728
Ellar SQLAlchemy Module simplifies the integration of SQLAlchemy and Alembic migration tooling into your ellar application.

ellar_sqlalchemy/__init__.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33
__version__ = "0.0.1"
44

55
from .module import EllarSQLAlchemyModule
6+
from .schemas import MigrationOption, SQLAlchemyConfig
67
from .services import EllarSQLAlchemyService
78

8-
__all__ = ["EllarSQLAlchemyModule", "EllarSQLAlchemyService"]
9+
__all__ = [
10+
"EllarSQLAlchemyModule",
11+
"EllarSQLAlchemyService",
12+
"SQLAlchemyConfig",
13+
"MigrationOption",
14+
]

ellar_sqlalchemy/cli/commands.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
1-
import click
1+
import ellar_cli.click as click
22
from ellar.app import current_injector
33

44
from ellar_sqlalchemy.services import EllarSQLAlchemyService
55

66
from .handlers import CLICommandHandlers
77

88

9+
def _get_handler_context(ctx: click.Context) -> CLICommandHandlers:
10+
db_service = current_injector.get(EllarSQLAlchemyService)
11+
return CLICommandHandlers(db_service)
12+
13+
914
@click.group()
1015
def db():
1116
"""- Perform Alembic Database Commands -"""
1217
pass
1318

1419

15-
def _get_handler_context(ctx: click.Context) -> CLICommandHandlers:
16-
db_service = current_injector.get(EllarSQLAlchemyService)
17-
return CLICommandHandlers(db_service)
18-
19-
2020
@db.command()
2121
@click.option(
2222
"-d",
@@ -385,7 +385,21 @@ def stamp(ctx: click.Context, directory, sql, tag, revision):
385385
handler.stamp(directory, revision, sql, tag)
386386

387387

388-
@db.command("init-migration")
388+
@db.command()
389+
@click.option(
390+
"-d",
391+
"--directory",
392+
default=None,
393+
help='Migration script directory (default is "migrations")',
394+
)
395+
@click.pass_context
396+
def check(ctx: click.Context, directory):
397+
"""Check if there are any new operations to migrate"""
398+
handler = _get_handler_context(ctx)
399+
handler.check(directory)
400+
401+
402+
@db.command("init")
389403
@click.option(
390404
"-d",
391405
"--directory",

ellar_sqlalchemy/cli/handlers.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
11
from __future__ import annotations
22

33
import argparse
4-
import logging
54
import os
6-
import sys
75
import typing as t
86
from functools import wraps
97
from pathlib import Path
108

9+
import click
1110
from alembic import command
1211
from alembic.config import Config as AlembicConfig
1312
from alembic.util.exc import CommandError
1413
from ellar.app import App
1514

1615
from ellar_sqlalchemy.services import EllarSQLAlchemyService
1716

18-
log = logging.getLogger(__name__)
1917
RevIdType = t.Union[str, t.List[str], t.Tuple[str, ...]]
2018

2119

@@ -31,8 +29,7 @@ def wrapped(*args: t.Any, **kwargs: t.Any) -> None:
3129
try:
3230
f(*args, **kwargs)
3331
except (CommandError, RuntimeError) as exc:
34-
log.error("Error: " + str(exc))
35-
sys.exit(1)
32+
raise click.ClickException(str(exc)) from exc
3633

3734
return wrapped
3835

ellar_sqlalchemy/exceptions.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# class NoMatch(Exception):
2+
# pass
3+
#
4+
#
5+
# class MultipleMatches(Exception):
6+
# pass

ellar_sqlalchemy/model/__init__.py

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,52 @@
1+
import typing as t
2+
3+
import sqlalchemy as sa
4+
import sqlalchemy.event as sa_event
5+
import sqlalchemy.orm as sa_orm
6+
17
from .base import Model
28
from .table import Table
3-
from .typeDecorator import GUID, GenericIP
9+
from .typeDecorator import (
10+
GUID,
11+
CroppingDetails,
12+
FileField,
13+
FileObject,
14+
GenericIP,
15+
ImageFileField,
16+
ImageFileObject,
17+
)
418
from .utils import make_metadata
519

20+
if t.TYPE_CHECKING:
21+
from sqlalchemy import * # type:ignore[assignment]
22+
from sqlalchemy.event import * # noqa
23+
from sqlalchemy.orm import * # noqa
24+
25+
from .table import Table # noqa
26+
627
__all__ = [
728
"Model",
829
"Table",
930
"make_metadata",
1031
"GUID",
1132
"GenericIP",
33+
"FileObject",
34+
"FileField",
35+
"ImageFileField",
36+
"ImageFileObject",
37+
"CroppingDetails",
1238
]
39+
40+
41+
def __getattr__(name: str) -> t.Any:
42+
if name == "event":
43+
return sa_event
44+
45+
if name.startswith("_"):
46+
raise AttributeError(name)
47+
48+
for mod in (sa, sa_orm):
49+
if hasattr(mod, name):
50+
return getattr(mod, name)
51+
52+
raise AttributeError(name)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy