]> git.ipfire.org Git - thirdparty/sqlalchemy/alembic.git/commitdiff
Add epoch as an option for file_template
authorCaio Carvalho <21188280+lowercase00@users.noreply.github.com>
Tue, 3 May 2022 17:20:18 +0000 (13:20 -0400)
committerFederico Caselli <cfederico87@gmail.com>
Fri, 6 May 2022 20:30:39 +0000 (20:30 +0000)
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

alembic/script/base.py
alembic/templates/generic/alembic.ini.mako
alembic/templates/multidb/alembic.ini.mako
alembic/templates/pylons/alembic.ini.mako
docs/build/tutorial.rst
docs/build/unreleased/1027.rst [new file with mode: 0644]
tests/test_mssql.py
tests/test_script_production.py

index cd81f375e6f9d5900cd0d003aff321dcc78d6d47..cae0a2bcedbc6435ebadfb46e32e2294906a56f2 100644 (file)
@@ -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,
index 5268e7cd7184d7ccb49fcfd31248a21b144d50ff..8aa47b19b5d15c176bda11bd296903b8e672581a 100644 (file)
@@ -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.
index 37376b2fdb9e496bb2dae8374fa097190870f823..5adef392fdee3cfd3327e7d4888ac4a8ded86970 100644 (file)
@@ -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.
index ed930dafc8d067dabaddc02b159c7c2579270524..82facf910fc0299f651f72d2310fcfed8c5fcd8a 100644 (file)
@@ -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.
index 5bfab916e823343d492f920b5310e54fff812a4d..17034c16a32ed4e39fa858f36717a33384bdc1bf 100644 (file)
@@ -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 (file)
index 0000000..d10b547
--- /dev/null
@@ -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.
index f2a84a7a71279cfa8f62336640b66c3ca3929b60..4bb618cd4b8917f104ea159a7734966a73c75b47 100644 (file)
@@ -1,4 +1,5 @@
 """Test op functions against MSSQL."""
+from __future__ import annotations
 
 from typing import Any
 from typing import Dict
index 05167f0b4865107da7d7f72c67cca97179fe011b..2cf9052ada43df8ae182b3d86d0039ca7a6457da 100644 (file)
@@ -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(),