From: Caio Carvalho <21188280+lowercase00@users.noreply.github.com> Date: Tue, 3 May 2022 17:20:18 +0000 (-0400) Subject: Add epoch as an option for file_template X-Git-Tag: rel_1_8_0~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0adcc749183abe17beab0baa07d8b1b1ac6a55d2;p=thirdparty%2Fsqlalchemy%2Falembic.git Add epoch as an option for file_template Added new token ``epoch`` to the ``file_template`` option, which will populate the integer epoch as determined by ``int(create_date.timestamp())``. Pull request courtesy Caio Carvalho. Fixes: #1027 Closes: #1028 Pull-request: https://github.com/sqlalchemy/alembic/pull/1028 Pull-request-sha: 27970cd5d4e047cb7aabd161c68b757b2ee3e4c4 Change-Id: I73e13009bae91e64681a605b3f0b62ea1e5fc464 --- diff --git a/alembic/script/base.py b/alembic/script/base.py index cd81f375..cae0a2bc 100644 --- a/alembic/script/base.py +++ b/alembic/script/base.py @@ -771,6 +771,7 @@ class ScriptDirectory: message: Optional[str], create_date: "datetime.datetime", ) -> str: + epoch = int(create_date.timestamp()) slug = "_".join(_slug_re.findall(message or "")).lower() if len(slug) > self.truncate_slug_length: slug = slug[: self.truncate_slug_length].rsplit("_", 1)[0] + "_" @@ -779,6 +780,7 @@ class ScriptDirectory: % { "rev": rev_id, "slug": slug, + "epoch": epoch, "year": create_date.year, "month": create_date.month, "day": create_date.day, diff --git a/alembic/templates/generic/alembic.ini.mako b/alembic/templates/generic/alembic.ini.mako index 5268e7cd..8aa47b19 100644 --- a/alembic/templates/generic/alembic.ini.mako +++ b/alembic/templates/generic/alembic.ini.mako @@ -6,6 +6,8 @@ script_location = ${script_location} # template used to generate migration file names; The default value is %%(rev)s_%%(slug)s # Uncomment the line below if you want the files to be prepended with date and time +# see https://alembic.sqlalchemy.org/en/latest/tutorial.html#editing-the-ini-file +# for all available tokens # file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s # sys.path path, will be prepended to sys.path if present. diff --git a/alembic/templates/multidb/alembic.ini.mako b/alembic/templates/multidb/alembic.ini.mako index 37376b2f..5adef392 100644 --- a/alembic/templates/multidb/alembic.ini.mako +++ b/alembic/templates/multidb/alembic.ini.mako @@ -6,6 +6,8 @@ script_location = ${script_location} # template used to generate migration file names; The default value is %%(rev)s_%%(slug)s # Uncomment the line below if you want the files to be prepended with date and time +# see https://alembic.sqlalchemy.org/en/latest/tutorial.html#editing-the-ini-file +# for all available tokens # file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s # sys.path path, will be prepended to sys.path if present. diff --git a/alembic/templates/pylons/alembic.ini.mako b/alembic/templates/pylons/alembic.ini.mako index ed930daf..82facf91 100644 --- a/alembic/templates/pylons/alembic.ini.mako +++ b/alembic/templates/pylons/alembic.ini.mako @@ -6,6 +6,8 @@ script_location = ${script_location} # template used to generate migration file names; The default value is %%(rev)s_%%(slug)s # Uncomment the line below if you want the files to be prepended with date and time +# see https://alembic.sqlalchemy.org/en/latest/tutorial.html#editing-the-ini-file +# for all available tokens # file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s # sys.path path, will be prepended to sys.path if present. diff --git a/docs/build/tutorial.rst b/docs/build/tutorial.rst index 5bfab916..17034c16 100644 --- a/docs/build/tutorial.rst +++ b/docs/build/tutorial.rst @@ -274,11 +274,16 @@ This file contains the following features: * ``%%(rev)s`` - revision id * ``%%(slug)s`` - a truncated string derived from the revision message + * ``%%(epoch)s`` - epoch timestamp based on the create date; this makes + use of the Python ``datetime.timestamp()`` method to produce an epoch + value. * ``%%(year)d``, ``%%(month).2d``, ``%%(day).2d``, ``%%(hour).2d``, ``%%(minute).2d``, ``%%(second).2d`` - components of the create date, by default ``datetime.datetime.now()`` unless the ``timezone`` configuration option is also used. + .. versionadded:: 1.8 added 'epoch' + * ``timezone`` - an optional timezone name (e.g. ``UTC``, ``EST5EDT``, etc.) that will be applied to the timestamp which renders inside the migration file's comment as well as within the filename. This option requires installing diff --git a/docs/build/unreleased/1027.rst b/docs/build/unreleased/1027.rst new file mode 100644 index 00000000..d10b5470 --- /dev/null +++ b/docs/build/unreleased/1027.rst @@ -0,0 +1,7 @@ +.. change:: + :tags: usecase, commands + :tickets: 1027 + + Added new token ``epoch`` to the ``file_template`` option, which will + populate the integer epoch as determined by ``int(create_date.timestamp())``. + Pull request courtesy Caio Carvalho. diff --git a/tests/test_mssql.py b/tests/test_mssql.py index f2a84a7a..4bb618cd 100644 --- a/tests/test_mssql.py +++ b/tests/test_mssql.py @@ -1,4 +1,5 @@ """Test op functions against MSSQL.""" +from __future__ import annotations from typing import Any from typing import Dict diff --git a/tests/test_script_production.py b/tests/test_script_production.py index 05167f0b..2cf9052a 100644 --- a/tests/test_script_production.py +++ b/tests/test_script_production.py @@ -8,6 +8,7 @@ from sqlalchemy import inspect from alembic import autogenerate from alembic import command +from alembic import testing from alembic import util from alembic.environment import EnvironmentContext from alembic.operations import ops @@ -185,6 +186,33 @@ class ScriptNamingTest(TestBase): ), ) + @testing.combinations( + ( + datetime.datetime(2012, 7, 25, 15, 8, 5, tzinfo=tz.gettz("UTC")), + "%s/versions/1343228885_12345_this_is_a_" + "message_2012_7_25_15_8_5.py", + ), + ( + datetime.datetime(2012, 7, 25, 15, 8, 6, tzinfo=tz.gettz("UTC")), + "%s/versions/1343228886_12345_this_is_a_" + "message_2012_7_25_15_8_6.py", + ), + ) + def test_epoch(self, create_date, expected): + script = ScriptDirectory( + _get_staging_directory(), + file_template="%(epoch)s_%(rev)s_%(slug)s_" + "%(year)s_%(month)s_" + "%(day)s_%(hour)s_" + "%(minute)s_%(second)s", + ) + eq_( + script._rev_path( + script.versions, "12345", "this is a message", create_date + ), + os.path.abspath(expected % _get_staging_directory()), + ) + def _test_tz(self, timezone_arg, given, expected): script = ScriptDirectory( _get_staging_directory(),