Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.8
python-version: '3.12'
- name: Install Flit
run: pip install flit
- name: Install Dependencies
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.8
python-version: '3.12'
- name: Install Flit
run: pip install flit
- name: Install Dependencies
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test_full.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
python-version: ['3.10', '3.11', '3.12', '3.13']

steps:
- uses: actions/checkout@v4
Expand All @@ -32,7 +32,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.8
python-version: '3.12'
- name: Install Flit
run: pip install flit
- name: Install Dependencies
Expand Down
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ help:
@fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'

clean: ## Removing cached python compiled files
find . -name \*pyc | xargs rm -fv
find . -name \*pyo | xargs rm -fv
find . -name \*~ | xargs rm -fv
find . -name "*.pyc" -type f -delete
find . -name "*.pyo" -type f -delete
find . -name "*~" -type f -delete
find . -name __pycache__ | xargs rm -rfv
find . -name .pytest_cache | xargs rm -rfv
find . -name .ruff_cache | xargs rm -rfv
Expand Down
17 changes: 17 additions & 0 deletions docs/multiple/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,23 @@ EllarSQLModule.setup(
)
```

## **Configuring Async Databases**
When configuring async databases,
you need to specify the `+asyncpg` or `+aiosqlite` suffix to the database URL in case of SQLite and PostgreSQL respectively.

For example, to configure an async database, you can use the following configuration:
```python
from ellar_sql import EllarSQLModule

EllarSQLModule.setup(
databases={
"default": "postgresql+asyncpg:///main",
"meta": "sqlite+aiosqlite:////path/to/meta.db",
},
migration_options={'directory': 'migrations'}
)
```

## **Defining Models and Tables with Different Databases**

**EllarSQL** creates **Metadata** and an **Engine** for each configured database.
Expand Down
30 changes: 15 additions & 15 deletions ellar_sql/cli/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ def db():
@click.option(
"--sql",
is_flag=True,
help="Don't emit SQL to database - dump to standard output " "instead",
help="Don't emit SQL to database - dump to standard output instead",
)
@click.option(
"--head",
default="head",
help="Specify head revision or <branchname>@head to base new " "revision on",
help="Specify head revision or <branchname>@head to base new revision on",
)
@click.option(
"--splice",
Expand All @@ -61,7 +61,7 @@ def db():
@click.option(
"--rev-id",
default=None,
help="Specify a hardcoded revision id instead of generating " "one",
help="Specify a hardcoded revision id instead of generating one",
)
@click.pass_context
def revision(
Expand Down Expand Up @@ -102,12 +102,12 @@ def revision(
@click.option(
"--sql",
is_flag=True,
help="Don't emit SQL to database - dump to standard output " "instead",
help="Don't emit SQL to database - dump to standard output instead",
)
@click.option(
"--head",
default="head",
help="Specify head revision or <branchname>@head to base new " "revision on",
help="Specify head revision or <branchname>@head to base new revision on",
)
@click.option(
"--splice",
Expand All @@ -127,7 +127,7 @@ def revision(
@click.option(
"--rev-id",
default=None,
help="Specify a hardcoded revision id instead of generating " "one",
help="Specify a hardcoded revision id instead of generating one",
)
@click.option(
"-x",
Expand Down Expand Up @@ -195,7 +195,7 @@ def edit(ctx, directory, revision):
@click.option(
"--rev-id",
default=None,
help="Specify a hardcoded revision id instead of generating " "one",
help="Specify a hardcoded revision id instead of generating one",
)
@click.argument("revisions", nargs=-1)
@click.pass_context
Expand All @@ -215,12 +215,12 @@ def merge(ctx, directory, message, branch_label, rev_id, revisions):
@click.option(
"--sql",
is_flag=True,
help="Don't emit SQL to database - dump to standard output " "instead",
help="Don't emit SQL to database - dump to standard output instead",
)
@click.option(
"--tag",
default=None,
help='Arbitrary "tag" name - can be used by custom env.py ' "scripts",
help='Arbitrary "tag" name - can be used by custom env.py scripts',
)
@click.option(
"-x",
Expand All @@ -246,12 +246,12 @@ def upgrade(ctx, directory, sql, tag, x_arg, revision):
@click.option(
"--sql",
is_flag=True,
help="Don't emit SQL to database - dump to standard output " "instead",
help="Don't emit SQL to database - dump to standard output instead",
)
@click.option(
"--tag",
default=None,
help='Arbitrary "tag" name - can be used by custom env.py ' "scripts",
help='Arbitrary "tag" name - can be used by custom env.py scripts',
)
@click.option(
"-x",
Expand Down Expand Up @@ -300,7 +300,7 @@ def show(ctx: click.Context, directory, revision):
"-i",
"--indicate-current",
is_flag=True,
help="Indicate current version (Alembic 0.9.9 or greater is " "required)",
help="Indicate current version (Alembic 0.9.9 or greater is required)",
)
@click.pass_context
def history(ctx: click.Context, directory, rev_range, verbose, indicate_current):
Expand Down Expand Up @@ -369,12 +369,12 @@ def current(ctx: click.Context, directory, verbose):
@click.option(
"--sql",
is_flag=True,
help="Don't emit SQL to database - dump to standard output " "instead",
help="Don't emit SQL to database - dump to standard output instead",
)
@click.option(
"--tag",
default=None,
help='Arbitrary "tag" name - can be used by custom env.py ' "scripts",
help='Arbitrary "tag" name - can be used by custom env.py scripts',
)
@click.argument("revision", default="head")
@click.pass_context
Expand Down Expand Up @@ -416,7 +416,7 @@ def check(ctx: click.Context, directory):
@click.option(
"--package",
is_flag=True,
help="Write empty __init__.py files to the environment and " "version locations",
help="Write empty __init__.py files to the environment and version locations",
)
@click.pass_context
def init(ctx: click.Context, directory, multiple, package):
Expand Down
5 changes: 5 additions & 0 deletions ellar_sql/factory/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@


class EllarSQLOptions(SQLAlchemyOptions):
# Type hints for SQLAlchemy-specific attributes
sqlalchemy_get_or_create: t.Tuple[str, ...]
sqlalchemy_session_persistence: str

@staticmethod
def _check_has_sqlalchemy_session_set(meta, value):
if value and hasattr(meta, "sqlalchemy_session"):
Expand All @@ -31,6 +35,7 @@ class EllarSQLFactory(SQLAlchemyModelFactory):
"""Factory for EllarSQL models."""

_options_class = EllarSQLOptions
_meta: EllarSQLOptions

class Meta:
abstract = True
Expand Down
6 changes: 3 additions & 3 deletions ellar_sql/model/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ def __new__(
)
if isinstance(options, dict):
options = ModelBaseConfig(**options)
assert isinstance(
options, ModelBaseConfig
), f"{options.__class__} is not a support ModelMetaOptions"
assert isinstance(options, ModelBaseConfig), (
f"{options.__class__} is not a support ModelMetaOptions"
)

if options.as_base:
declarative_bases = _get_declarative_bases(options.use_bases)
Expand Down
9 changes: 9 additions & 0 deletions ellar_sql/model/typeDecorator/file/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ class File(BaseFile, AttributeDictAccessMixin):

files: t.List[str]

# Type hints for dict-like methods from parent classes
if t.TYPE_CHECKING:

def get(self, __key: str, __default: t.Any = None) -> t.Any: ...

def __setitem__(self, __key: str, __value: t.Any) -> None: ...

def __getitem__(self, __key: str) -> t.Any: ...

def __init__(
self,
content: t.Any = None,
Expand Down
6 changes: 3 additions & 3 deletions ellar_sql/pagination/decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ def _prepare_template_response(
]:
if isinstance(res, tuple):
filter_query, extra_context = res
assert isinstance(
extra_context, dict
), "When using as `template_context`, route function should return a tuple(select, {})"
assert isinstance(extra_context, dict), (
"When using as `template_context`, route function should return a tuple(select, {})"
)

elif isinstance(res, dict):
filter_query = None
Expand Down
6 changes: 3 additions & 3 deletions ellar_sql/services/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ def engines(self) -> t.Dict[str, sa.Engine]:

@property
def engine(self) -> sa.Engine:
assert self._engines[self].get(
DEFAULT_KEY
), f"{self.__class__.__name__} configuration is not ready"
assert self._engines[self].get(DEFAULT_KEY), (
f"{self.__class__.__name__} configuration is not ready"
)
return self._engines[self][DEFAULT_KEY]

def _setup(
Expand Down
4 changes: 3 additions & 1 deletion samples/db-learning/db_learning/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ def seed_user():
session = db_service.session_factory()

for i in range(300):
session.add(User(username=f"username-{i+1}", email=f"user{i+1}doe@example.com"))
session.add(
User(username=f"username-{i + 1}", email=f"user{i + 1}doe@example.com")
)

session.commit()
db_service.session_factory.remove()
4 changes: 3 additions & 1 deletion samples/index-script/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ def main():
session = db_service.session_factory()

for i in range(50):
session.add(User(username=f"username-{i+1}", email=f"user{i+1}doe@example.com"))
session.add(
User(username=f"username-{i + 1}", email=f"user{i + 1}doe@example.com")
)

session.commit()
rows = session.execute(model.select(User)).scalars()
Expand Down
12 changes: 3 additions & 9 deletions tests/test_migrations/test_migrations_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@
def test_migrate_upgrade():
result = run_command("default.py db init")
assert result.returncode == 0
assert (
b"tests/dumbs/default/migrations/alembic.ini' before proceeding."
in result.stdout
)
assert b"default/migrations/alembic.ini before proceeding." in result.stdout

result = run_command("default.py db check")
assert result.returncode == 1
Expand Down Expand Up @@ -36,7 +33,7 @@ def test_migrate_upgrade_custom_directory():
result = run_command("custom_directory.py db init")
assert result.returncode == 0
assert (
b"tests/dumbs/custom_directory/temp_migrations/alembic.ini' before proceeding."
b"custom_directory/temp_migrations/alembic.ini before proceeding."
in result.stdout
)

Expand Down Expand Up @@ -138,10 +135,7 @@ def test_other_alembic_commands():
def test_migrate_upgrade_async():
result = run_command("default_async.py db init")
assert result.returncode == 0
assert (
b"tests/dumbs/default_async/migrations/alembic.ini' before proceeding."
in result.stdout
)
assert b"default_async/migrations/alembic.ini before proceeding." in result.stdout

result = run_command("default_async.py db check")
assert result.returncode == 1
Expand Down
8 changes: 2 additions & 6 deletions tests/test_migrations/test_multiple_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ def test_migrate_upgrade_for_multiple_database():
with set_env_variable("multiple_db", "true"):
result = run_command("multiple_database.py db init -m")
assert result.returncode == 0
assert (
b"tests/dumbs/multiple/migrations/alembic.ini' before proceeding."
in result.stdout
)
assert b"multiple/migrations/alembic.ini before proceeding." in result.stdout

result = run_command("multiple_database.py db check")
assert result.returncode == 1
Expand Down Expand Up @@ -62,8 +59,7 @@ def test_migrate_upgrade_for_multiple_database_async():
result = run_command("multiple_database_async.py db init -m")
assert result.returncode == 0
assert (
b"tests/dumbs/multiple_async/migrations/alembic.ini' before proceeding."
in result.stdout
b"multiple_async/migrations/alembic.ini before proceeding." in result.stdout
)

result = run_command("multiple_database_async.py db check")
Expand Down