diff --git a/edgy/cli/templates/default/script.py.mako b/edgy/cli/templates/default/script.py.mako index a19686c8..299e60ee 100644 --- a/edgy/cli/templates/default/script.py.mako +++ b/edgy/cli/templates/default/script.py.mako @@ -5,9 +5,12 @@ Revises: ${down_revision | comma,n} Create Date: ${create_date} """ +<% + from edgy.utils.hashing import hash_to_identifier, hash_to_identifier_as_string +%> +from __future__ import annotations from alembic import op import sqlalchemy as sa -from edgy.utils.hashing import hash_to_identifier ${imports if imports else ""} # revision identifiers, used by Alembic. @@ -16,21 +19,24 @@ down_revision = ${repr(down_revision)} branch_labels = ${repr(branch_labels)} depends_on = ${repr(depends_on)} +${hash_to_identifier_as_string} + def upgrade(engine_name: str = "") -> None: - fn = globals().get(f"upgrade_{hash_to_identifier(engine_name)}") + # hash_to_identifier adds already an "_" + fn = globals().get(f"upgrade{hash_to_identifier(engine_name)}") if fn is not None: fn() def downgrade(engine_name: str = "") -> None: - fn = globals().get(f"downgrade_{hash_to_identifier(engine_name)}") + # hash_to_identifier adds already an "_" + fn = globals().get(f"downgrade{hash_to_identifier(engine_name)}") if fn is not None: fn() <% from edgy import monkay - from edgy.utils.hashing import hash_to_identifier db_names = monkay.settings.migrate_databases %> @@ -39,13 +45,13 @@ def downgrade(engine_name: str = "") -> None: % for db_name in db_names: -def ${f"upgrade_{hash_to_identifier(db_name or '')}"}(): +def ${f"upgrade{hash_to_identifier(db_name or '')}"}(): # Migration of: # ${db_name or 'main database'} ${context.get(f"{db_name or ''}_upgrades", "pass")} -def ${f"downgrade_{hash_to_identifier(db_name or '')}"}(): +def ${f"downgrade{hash_to_identifier(db_name or '')}"}(): # Migration of: # ${db_name or 'main database'} ${context.get(f"{db_name or ''}_downgrades", "pass")} diff --git a/edgy/cli/templates/plain/script.py.mako b/edgy/cli/templates/plain/script.py.mako index 0b9beead..d1c90f01 100644 --- a/edgy/cli/templates/plain/script.py.mako +++ b/edgy/cli/templates/plain/script.py.mako @@ -5,6 +5,7 @@ Revises: ${down_revision | comma,n} Create Date: ${create_date} """ +from __future__ import annotations from alembic import op import sqlalchemy as sa ${imports if imports else ""} diff --git a/edgy/cli/templates/url/script.py.mako b/edgy/cli/templates/url/script.py.mako index 10c1ef78..847ae6f6 100644 --- a/edgy/cli/templates/url/script.py.mako +++ b/edgy/cli/templates/url/script.py.mako @@ -5,11 +5,14 @@ Revises: ${down_revision | comma,n} Create Date: ${create_date} """ +<% + from edgy.utils.hashing import hash_to_identifier, hash_to_identifier_as_string +%> +from __future__ import annotations from typing import TYPE_CHECKING, Optional from alembic import op import sqlalchemy as sa -from edgy.utils.hashing import hash_to_identifier ${imports if imports else ""} if TYPE_CHECKING: @@ -21,16 +24,22 @@ down_revision = ${repr(down_revision)} branch_labels = ${repr(branch_labels)} depends_on = ${repr(depends_on)} + +${hash_to_identifier_as_string} + + def upgrade(url: Optional["DatabaseURL"] = None) -> None: urlstring = "" if url is None else f"{url.username}:{url.netloc}" - fn = globals().get(f"upgrade_{hash_to_identifier(urlstring)}") + # hash_to_identifier adds already an "_" + fn = globals().get(f"upgrade{hash_to_identifier(urlstring)}") if fn is not None: fn() def downgrade(url: Optional["DatabaseURL"] = None) -> None: urlstring = "" if url is None else f"{url.username}:{url.netloc}" - fn = globals().get(f"downgrade_{hash_to_identifier(urlstring)}") + # hash_to_identifier adds already an "_" + fn = globals().get(f"downgrade{hash_to_identifier(urlstring)}") if fn is not None: fn() @@ -53,13 +62,13 @@ def downgrade(url: Optional["DatabaseURL"] = None) -> None: % for db_name in db_names: -def ${f"upgrade_{hash_to_identifier(url_for_name(db_name))}"}(): +def ${f"upgrade{hash_to_identifier(url_for_name(db_name))}"}(): # Migration of: # ${url_for_name(db_name)} (${db_name or 'main database'}) ${context.get(f"{db_name or ''}_upgrades", "pass")} -def ${f"downgrade_{hash_to_identifier(url_for_name(db_name))}"}(): +def ${f"downgrade{hash_to_identifier(url_for_name(db_name))}"}(): # Migration of: # ${url_for_name(db_name)} (${db_name or 'main database'}) ${context.get(f"{db_name or ''}_downgrades", "pass")} diff --git a/edgy/utils/hashing.py b/edgy/utils/hashing.py index 848411a3..9b7d7f92 100644 --- a/edgy/utils/hashing.py +++ b/edgy/utils/hashing.py @@ -1,9 +1,10 @@ +from __future__ import annotations + from base64 import b32encode from hashlib import blake2b -from typing import Union -def hash_to_identifier(key: Union[str, bytes]) -> str: +def hash_to_identifier(key: str | bytes) -> str: """ A generic hasher for keys, which output stays a valid name for python and other languages. @@ -16,4 +17,17 @@ def hash_to_identifier(key: Union[str, bytes]) -> str: if isinstance(key, str): key = key.encode() # prefix with _ for preventing a name starting with a number + # Note: the prefixing with underscore is expected by migrations + return f"_{b32encode(blake2b(key, digest_size=16).digest()).decode().rstrip('=')}" + + +# for migrations +# needs however either python 3.10 or from __future__ import annotations +hash_to_identifier_as_string: str = """ +def hash_to_identifier(key: str | bytes) -> str: + from base64 import b32encode + from hashlib import blake2b + if isinstance(key, str): + key = key.encode() return f"_{b32encode(blake2b(key, digest_size=16).digest()).decode().rstrip('=')}" +"""