From f2ba80840490068f418ae6fb27c9ef08c821051a Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Tue, 20 May 2025 14:35:53 -0400 Subject: [PATCH] doc edits. Also more changes are needed as we observe alembic does not run without alembic.ini present, which it should. Change-Id: Iff2393c79d3cb8b7ed8e653a08cc5f579fa31717 --- alembic/templates/async/alembic.ini.mako | 6 +- alembic/templates/generic/alembic.ini.mako | 6 +- alembic/templates/multidb/alembic.ini.mako | 10 ++- alembic/templates/pyproject/alembic.ini.mako | 3 + docs/build/front.rst | 36 +++++------ docs/build/tutorial.rst | 66 ++++++++++++-------- 6 files changed, 79 insertions(+), 48 deletions(-) diff --git a/alembic/templates/async/alembic.ini.mako b/alembic/templates/async/alembic.ini.mako index c46fe744..782524e2 100644 --- a/alembic/templates/async/alembic.ini.mako +++ b/alembic/templates/async/alembic.ini.mako @@ -81,6 +81,9 @@ path_separator = os # are written from script.py.mako # output_encoding = utf-8 +# database URL. This is consumed by the user-maintained env.py script only. +# other means of configuring database URLs may be customized within the env.py +# file. sqlalchemy.url = driver://user:pass@localhost/dbname @@ -101,7 +104,8 @@ sqlalchemy.url = driver://user:pass@localhost/dbname # ruff.executable = %(here)s/.venv/bin/ruff # ruff.options = check --fix REVISION_SCRIPT_FILENAME -# Logging configuration +# Logging configuration. This is also consumed by the user-maintained +# env.py script only. [loggers] keys = root,sqlalchemy,alembic diff --git a/alembic/templates/generic/alembic.ini.mako b/alembic/templates/generic/alembic.ini.mako index af12a0db..cb4e2bf3 100644 --- a/alembic/templates/generic/alembic.ini.mako +++ b/alembic/templates/generic/alembic.ini.mako @@ -81,6 +81,9 @@ path_separator = os # are written from script.py.mako # output_encoding = utf-8 +# database URL. This is consumed by the user-maintained env.py script only. +# other means of configuring database URLs may be customized within the env.py +# file. sqlalchemy.url = driver://user:pass@localhost/dbname @@ -101,7 +104,8 @@ sqlalchemy.url = driver://user:pass@localhost/dbname # ruff.executable = %(here)s/.venv/bin/ruff # ruff.options = check --fix REVISION_SCRIPT_FILENAME -# Logging configuration +# Logging configuration. This is also consumed by the user-maintained +# env.py script only. [loggers] keys = root,sqlalchemy,alembic diff --git a/alembic/templates/multidb/alembic.ini.mako b/alembic/templates/multidb/alembic.ini.mako index 699765c5..2680ef68 100644 --- a/alembic/templates/multidb/alembic.ini.mako +++ b/alembic/templates/multidb/alembic.ini.mako @@ -80,6 +80,13 @@ path_separator = os # are written from script.py.mako # output_encoding = utf-8 +# for multiple database configuration, new named sections are added +# which each include a distinct ``sqlalchemy.url`` entry. A custom value +# ``databases`` is added which indicates a listing of the per-database sections. +# The ``databases`` entry as well as the URLs present in the ``[engine1]`` +# and ``[engine2]`` sections continue to be consumed by the user-maintained env.py +# script only. + databases = engine1, engine2 [engine1] @@ -105,7 +112,8 @@ sqlalchemy.url = driver://user:pass@localhost/dbname2 # ruff.executable = %(here)s/.venv/bin/ruff # ruff.options = check --fix REVISION_SCRIPT_FILENAME -# Logging configuration +# Logging configuration. This is also consumed by the user-maintained +# env.py script only. [loggers] keys = root,sqlalchemy,alembic diff --git a/alembic/templates/pyproject/alembic.ini.mako b/alembic/templates/pyproject/alembic.ini.mako index fae3c141..3d10f0e4 100644 --- a/alembic/templates/pyproject/alembic.ini.mako +++ b/alembic/templates/pyproject/alembic.ini.mako @@ -2,6 +2,9 @@ [alembic] +# database URL. This is consumed by the user-maintained env.py script only. +# other means of configuring database URLs may be customized within the env.py +# file. sqlalchemy.url = driver://user:pass@localhost/dbname diff --git a/docs/build/front.rst b/docs/build/front.rst index 196a7ead..bb3d531b 100644 --- a/docs/build/front.rst +++ b/docs/build/front.rst @@ -30,45 +30,41 @@ for a project**; there are many such approaches. The documentation below is provided only for those users who otherwise have no specific project setup chosen. -To build a virtual environment for a specific project, first we assume that -`Python virtualenv `_ is installed -systemwide. Then:: +To build a virtual environment for a specific project, a virtual environment +can be created using the +`Python venv library `_:: $ cd /path/to/your/project - $ virtualenv .venv + $ python -m venv .venv There is now a Python interpreter that you can access in ``/path/to/your/project/.venv/bin/python``, as well as the `pip `_ installer tool in ``/path/to/your/project/.venv/bin/pip``. +Next,the ``activate`` command installed by venv can be used so that +all binaries local to this new Python environment are in the local path:: + + $ source /path/to/your/project/.venv/bin/activate + We now install Alembic as follows:: - $ /path/to/your/project/.venv/bin/pip install alembic + $ pip install alembic The install will add the ``alembic`` command to the virtual environment. All operations with Alembic in terms of this specific virtual environment will then proceed through the usage of this command, as in:: - $ /path/to/your/project/.venv/bin/alembic init alembic + $ alembic init alembic -The next step is **optional**. If our project itself has a ``setup.py`` -file, we can also install it in the local virtual environment in -`editable mode `_:: +Finally, assuming your project is itself installable, meaning it has a +``pyproject.toml`` file, and/or ``setup.py`` script, the local project can +be made a part of the same local environment by installing it with ``pip``, +optionally using "editable" mode:: - $ /path/to/your/project/.venv/bin/pip install -e . + $ pip install -e . -If we don't "install" the project locally, that's fine as well; the default -``alembic.ini`` file includes a directive ``prepend_sys_path = .`` so that the -local path is also in ``sys.path``. This allows us to run the ``alembic`` -command line tool from this directory without our project being "installed" in -that environment. -As a final step, the `virtualenv activate `_ -tool can be used so that the ``alembic`` command is available without any -path information, within the context of the current shell:: - - $ source /path/to/your/project/.venv/bin/activate Dependencies ------------ diff --git a/docs/build/tutorial.rst b/docs/build/tutorial.rst index 507f3e8e..e3ddcfbe 100644 --- a/docs/build/tutorial.rst +++ b/docs/build/tutorial.rst @@ -6,15 +6,15 @@ Alembic provides for the creation, management, and invocation of *change managem scripts for a relational database, using SQLAlchemy as the underlying engine. This tutorial will provide a full introduction to the theory and usage of this tool. -To begin, make sure Alembic is installed as described at :ref:`installation`. -As stated in the linked document, it is usually preferable that Alembic is +To begin, make sure Alembic is installed; a common way to install within a +local virtual environment is described at :ref:`installation`. +As illustrated in that chapter, it is useful to have Alembic installed in the **same module / Python path as that of the target project**, usually using a `Python virtual environment `_, so that when the ``alembic`` command is run, the Python script which is invoked by ``alembic``, namely your project's ``env.py`` script, will have access to your application's models. -This is not strictly necessary in all cases, however in the vast majority of -cases is usually preferred. +This is not strictly necessary, however is usually preferred. The tutorial below assumes the ``alembic`` command line utility is present in the local path and when invoked, will have access to the same Python module @@ -106,8 +106,9 @@ Where above, the ``init`` command was called to generate a migrations directory Please edit configuration/connection/logging settings in '/path/to/yourproject/alembic.ini' before proceeding. -Alembic also includes other environment templates. These can be listed out using the ``list_templates`` -command:: +The above layout is produced using a layout template called ``generic``. +Alembic also includes other environment templates. These can be listed out +using the ``list_templates`` command:: $ alembic list_templates Available templates: @@ -121,23 +122,28 @@ command:: alembic init --template generic ./scripts -.. versionchanged:: 1.8 The "pylons" environment template has been removed. - .. versionchanged:: 1.16.0 A new ``pyproject`` template has been added. See - the section :re3f:`using_pep_621` for background. + the section :ref:`using_pep_621` for background. + -` .. _tutorial_alembic_ini: Editing the .ini File ===================== -Alembic placed a file ``alembic.ini`` into the current directory. This is a file that the ``alembic`` -script looks for when invoked. This file can exist in a different directory, with the location to it -specified by either the ``--config`` option for the ``alembic`` runner or the ``ALEMBIC_CONFIG`` -environment variable (the former takes precedence). +Alembic placed a file ``alembic.ini`` into the current directory. Alembic looks +in the current directory for this file when any other commands are run; to +indicate an alternative location, the ``--config`` option may be used, or the +``ALEMBIC_CONFIG`` environment variable may be set. + +.. tip:: -The file generated with the "generic" configuration looks like:: + The file generated with the ``generic`` configuration template contains all directives + for both source code configuration as well as database configuration. When using + the ``pyproject`` template, the source code configuration elements will instead + be in a separate ``pyproject.toml`` file, described in the :ref:`next section `. + +The all-in-one .ini file created by ``generic`` is illustrated below:: # A generic, single database configuration. @@ -223,6 +229,9 @@ The file generated with the "generic" configuration looks like:: # are written from script.py.mako # output_encoding = utf-8 + # database URL. This is consumed by the user-maintained env.py script only. + # other means of configuring database URLs may be customized within the env.py + # file. sqlalchemy.url = driver://user:pass@localhost/dbname # [post_write_hooks] @@ -243,7 +252,8 @@ The file generated with the "generic" configuration looks like:: # ruff.executable = %(here)s/.venv/bin/ruff # ruff.options = check --fix REVISION_SCRIPT_FILENAME - # Logging configuration + # Logging configuration. This is also consumed by the user-maintained + # env.py script only. [loggers] keys = root,sqlalchemy,alembic @@ -278,10 +288,12 @@ The file generated with the "generic" configuration looks like:: format = %(levelname)-5.5s [%(name)s] %(message)s datefmt = %H:%M:%S -The file is read using Python's :class:`ConfigParser.SafeConfigParser` object. The -``%(here)s`` variable is provided as a substitution variable, which -can be used to produce absolute pathnames to directories and files, as we do above -with the path to the Alembic script location. +The ``alembic.ini`` file is consumed by Alembic using Python's +`configparser.ConfigParser `_ +library. The ``%(here)s`` variable is +provided as a substitution which is populated with the absolute path to the +``alembic.ini`` file itself. This can be used to produce correct pathnames +to directories and files relative to where the config file is located. This file contains the following features: @@ -334,8 +346,6 @@ This file contains the following features: 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 Python>=3.9 @@ -422,10 +432,12 @@ Use of ``pyproject.toml`` does not preclude having an ``alembic.ini`` file as well, as ``alembic.ini`` is still the default location for **deployment** details such as database URLs, connectivity options, and logging to be present. However, as connectivity and logging is consumed only by user-managed code -within the ``env.py`` file, it is feasible that the environment would not +within the ``env.py`` file, it is feasible to have an environment that does not require the ``alembic.ini`` file itself to be present at all, if these configurational elements are consumed from other places elsewhere in the -application. +application. Alembic will still run successfully if only a ``pyproject.toml`` +file is present and no ``alembic.ini`` is found. + To start with a pyproject configuration, the most straightforward approach is to use the ``pyproject`` template:: @@ -533,9 +545,13 @@ only database configuration and logging configuration:: [alembic] + # database URL. This is consumed by the user-maintained env.py script only. + # other means of configuring database URLs may be customized within the env.py + # file. sqlalchemy.url = driver://user:pass@localhost/dbname - # Logging configuration + # Logging configuration. This is also consumed by the user-maintained + # env.py script only. [loggers] keys = root,sqlalchemy,alembic -- 2.47.3