Skip to content

Commit

Permalink
Changes:
Browse files Browse the repository at this point in the history
- remove underscore
- future proof hashed migrations
  • Loading branch information
devkral committed Dec 16, 2024
1 parent ead9da0 commit e7533cd
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 13 deletions.
18 changes: 12 additions & 6 deletions edgy/cli/templates/default/script.py.mako
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
%>

Expand All @@ -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")}
Expand Down
1 change: 1 addition & 0 deletions edgy/cli/templates/plain/script.py.mako
Original file line number Diff line number Diff line change
Expand Up @@ -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 ""}
Expand Down
19 changes: 14 additions & 5 deletions edgy/cli/templates/url/script.py.mako
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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()

Expand All @@ -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")}
Expand Down
18 changes: 16 additions & 2 deletions edgy/utils/hashing.py
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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('=')}"
"""

0 comments on commit e7533cd

Please sign in to comment.