U ofV@sJddlmZddlmZddlmZddlmZddlZddlZddl Z ddl m Z ddl m Z ddl m Z dd l mZdd l mZdd l mZdd l mZdd l mZddl mZddlmZddlmZddlmZddlmZddlmZGdddZGdddeddZGdddZd%dddd d!d"d#Zed$krFedS)&) annotations)ArgumentParser) Namespace) ConfigParserN)Any)cast)Dict)Mapping)Optional)overload)Sequence)TextIO)Union) TypedDict) __version__)command)util)compatc @seZdZUdZdddejdedfdddddd d d d d dZdZ de d<dZ de d<dZ de d<ej ddddZddd dddZej ddddZddddZed?dd d d!d"d#Zedd$d$d!d%d#Zedd&d'd!d(d#Zd@dd)d)d!d*d#Zddd d+d,d-Zdd d.d/d0Zdddd d1d2d3ZdAddd4d4d5d6d7Zedddd!d8d9ZedBdd4d4d!d:d9ZdCdd4d4d!d;d9Zej dZdS)DConfiga` Represent an Alembic configuration. Within an ``env.py`` script, this is available via the :attr:`.EnvironmentContext.config` attribute, which in turn is available at ``alembic.context``:: from alembic import context some_param = context.config.get_main_option("my option") When invoking Alembic programmatically, a new :class:`.Config` can be created by passing the name of an .ini file to the constructor:: from alembic.config import Config alembic_cfg = Config("/path/to/yourapp/alembic.ini") With a :class:`.Config` object, you can then run Alembic commands programmatically using the directives in :mod:`alembic.command`. The :class:`.Config` object can also be constructed without a filename. Values can be set programmatically, and new sections will be created as needed:: from alembic.config import Config alembic_cfg = Config() alembic_cfg.set_main_option("script_location", "myapp:migrations") alembic_cfg.set_main_option("sqlalchemy.url", "postgresql://foo/bar") alembic_cfg.set_section_option("mysection", "foo", "bar") .. warning:: When using programmatic configuration, make sure the ``env.py`` file in use is compatible with the target configuration; including that the call to Python ``logging.fileConfig()`` is omitted if the programmatic configuration doesn't actually include logging directives. For passing non-string values to environments, such as connections and engines, use the :attr:`.Config.attributes` dictionary:: with engine.begin() as connection: alembic_cfg.attributes['connection'] = connection command.upgrade(alembic_cfg, "head") :param file\_: name of the .ini file to open. :param ini_section: name of the main Alembic section within the .ini file :param output_buffer: optional file-like input buffer which will be passed to the :class:`.MigrationContext` - used to redirect the output of "offline generation" when using Alembic programmatically. :param stdout: buffer where the "print" output of commands will be sent. Defaults to ``sys.stdout``. :param config_args: A dictionary of keys and values that will be used for substitution in the alembic config file. The dictionary as given is **copied** to a new one, stored locally as the attribute ``.config_args``. When the :attr:`.Config.file_config` attribute is first invoked, the replacement variable ``here`` will be added to this dictionary before the dictionary is passed to ``ConfigParser()`` to parse the .ini file. :param attributes: optional dictionary of arbitrary Python keys/values, which will be populated into the :attr:`.Config.attributes` dictionary. .. seealso:: :ref:`connection_sharing` Nalembicz"Union[str, os.PathLike[str], None]strzOptional[TextIO]r zOptional[Namespace]zMapping[str, Any]zOptional[Dict[str, Any]]None)file_ ini_section output_bufferstdoutcmd_opts config_args attributesreturncCs<||_||_||_||_||_t||_|r8|j|dS)z Construct a new :class:`.Config`N) config_file_nameconfig_ini_sectionrrrdictrrupdate)selfrrrrrrrr&>> config.print_stdout('Some text %s', 'arg') Some Text arg  N)rrZwrite_outstreamrmessaging_opts)r%r*r+outputr&r&r' print_stdoutszConfig.print_stdoutrcCs^|jrtjtj|j}nd}||jd<t|j}|jrNt||jgn | |j |S)aReturn the underlying ``ConfigParser`` object. Direct access to the .ini file is available here, though the :meth:`.Config.get_section` and :meth:`.Config.get_main_option` methods provide a possibly simpler interface. here) r!ospathabspathdirnamerrrZread_config_parser add_sectionr")r%r1 file_configr&r&r'r7s    zConfig.file_configcCs,ddl}tjtj|j}tj|dS)zReturn the directory where Alembic setup templates are found. This method is used by the alembic ``init`` and ``list_templates`` commands. rNZ templates)rr2r3r4r5__file__join)r%r package_dirr&r&r'get_template_directoryszConfig.get_template_directory.zOptional[Dict[str, str]])namedefaultr cCsdSNr&r%r<r=r&r&r' get_sectionszConfig.get_sectionzDict[str, str]cCsdSr>r&r?r&r&r'r@szMapping[str, str]z(Union[Dict[str, str], Mapping[str, str]]cCsdSr>r&r?r&r&r'r@szOptional[Mapping[str, str]]cCs |j|s|St|j|S)zReturn all the configuration options from a given .ini file section as a dictionary. If the given section does not exist, the value of ``default`` is returned, which is expected to be a dictionary or other mapping. )r7 has_sectionr#itemsr?r&r&r'r@s )r<valuer cCs||j||dS)a:Set an option programmatically within the 'main' section. This overrides whatever was in the .ini file. :param name: name of the value :param value: the value. Note that this value is passed to ``ConfigParser.set``, which supports variable interpolation using pyformat (e.g. ``%(some_value)s``). A raw percent sign not part of an interpolation symbol must therefore be escaped, e.g. ``%%``. The given value may refer to another value already in the file using the interpolation format. N)set_section_optionr")r%r<rCr&r&r'set_main_optionszConfig.set_main_option)r<r cCs|j|j|dSr>)r7 remove_optionr")r%r<r&r&r'remove_main_optionszConfig.remove_main_option)sectionr<rCr cCs,|j|s|j||j|||dS)aSet an option programmatically within the given section. The section is created if it doesn't exist already. The value here will override whatever was in the .ini file. :param section: name of the section :param name: name of the value :param value: the value. Note that this value is passed to ``ConfigParser.set``, which supports variable interpolation using pyformat (e.g. ``%(some_value)s``). A raw percent sign not part of an interpolation symbol must therefore be escaped, e.g. ``%%``. The given value may refer to another value already in the file using the interpolation format. N)r7rAr6set)r%rHr<rCr&r&r'rDs  zConfig.set_section_option Optional[str])rHr<r=r cCsD|j|s td|j|f|j||r<|j||S|SdS)z9Return an option from the given section of the .ini file.z6No config file %r found, or file has no '[%s]' sectionN)r7rAr CommandErrorr! has_optionget)r%rHr<r=r&r&r'get_section_option*s zConfig.get_section_optioncCsdSr>r&r?r&r&r'get_main_option8szConfig.get_main_optioncCsdSr>r&r?r&r&r'rO;scCs||j||S)zReturn an option from the 'main' section of the .ini file. This defaults to being a key from the ``[alembic]`` section, unless the ``-n/--name`` flag were used to indicate a different section. )rNr"r?r&r&r'rO@s MessagingOptionsc Cstttdt|jddiS)zThe messaging options.quietF)rrPr immutabledictgetattrrr)r&r&r'r-Ls zConfig.messaging_opts).)N)N)N)N)__name__ __module__ __qualname____doc__sysrrrRr(r__annotations__r!r"Zmemoized_propertyrr/r7r;r r@rErGrDrNrOr-r&r&r&r'rsR J    rc@seZdZUded<dS)rPboolrQN)rTrUrVrYr&r&r&r'rPWs rPF)totalc@sReZdZddddddZdddddZd d dd d d ZddddddZdS) CommandLineNrJr)progr cCs||dSr>)_generate_args)r%r]r&r&r'r(\szCommandLine.__init__c sddddddfdd }t|d}|jddd td |jd d ttjd ddd|jddtddd|jdddd|jdddd|jddddd|}tj dd iid!d"t tDD]$t rƈj d#d$krƈjd%krt}|d&dk r<|d#d't|d& }|d#t|d& d}n|d#d'd}g}krnfd(d"|D}j}|rg} |d)D]&} | sqn| | qng} |jj d*| d+|||j||fd,q||_dS)-Nrr)fnparser positionalkwargsr c sddtdtddfddttdd fd td d d fdttdd fdttdd fdtd dd fdtddd fdttdd fdttdd fdttdd fddtd dd fd td d!d fd"td d#d fd$d%td&d'd fd(d)td d*d fd+td d,d fd-td d.d fd/}d0d1d2d3}|D]:}||kr||}|d4d5|d5}}|j||q|D]X}|d6ksz|kr||d6krjd6d7|d6d8nj|||d9qPdS):Nz-tz --templateZgenericz"Setup template for use with 'init')r=typehelpz-mz --messagez%Message string to use with 'revision')rcrdz--sql store_truez\Don't emit SQL to database - dump to standard output/file instead. See docs on offline mode.actionrdz--tagz@head to base new revision on.z--splicez6Allow a non-head revision as the 'head' to splice ontoz --depends-onappendzNSpecify one or more revision identifiers which this revision should depend on.z--rev-idz9Specify a hardcoded revision id instead of generating onez--version-pathz2Specify specific path from config for version filez--branch-labelz3Specify a branch label to apply to the new revisionz-vz --verbosezUse more verbose outputz--resolve-dependenciesz+Treat dependency versions as down revisionsz--autogeneratezgPopulate revision script with candidate migration operations, based on comparison of database to model.z-rz --rev-rangestorez1Specify a revision range; format is [start]:[end]z-iz--indicate-currentzIndicate the current revisionz--purgez7Unconditionally erase the version table before stampingz --packagezFWrite empty __init__.py files to the environment and version locations)templatemessagesqltagheadZspliceZ depends_onZrev_idZ version_pathZ branch_labelverboseZresolve_dependenciesZ autogenerateZ rev_rangeZindicate_currentpurgepackagezlocation of scripts directoryzrevision identifierz/one or more revisions, or 'heads' for all heads) directoryrevision revisionsrrt+)nargsrdrd)r#r add_argumentrM) r_r`rarbZ kwargs_optsZpositional_helpr+argskw)positional_translations subparserr&r' add_options`s                z/CommandLine._generate_args..add_optionsr]z --versionversionz %%(prog)s %s)rgrz-cz--configZALEMBIC_CONFIGz alembic.inizaAlternate config file; defaults to value of ALEMBIC_CONFIG environment variable, or "alembic.ini")rcr=rdz-nz--namerz6Name of section in .ini file to use for Alembic configz-xrhzlAdditional arguments consumed by custom env.py scripts, e.g. -x setting1=somesetting -x setting2=somesettingrfz --raiseerrrez!Raise a full stack trace on errorz-qz--quietzDo not log to std output.rsrtcSsg|]}tt|qSr&)rSr).0nr&r&r' 1sz.CommandLine._generate_args..r_zalembic.commandrcsg|]}||qSr&)rM)rr<)r_r|r&r'r@sr, rx)cmd)rryrrr2environrMadd_subparsersrZstampdirinspect isfunctionrTrUrZinspect_getfullargspeclenrWsplitstriprh add_parserr9 set_defaultsr`) r%r]r~r`Z subparsersspecrakwarghelp_ help_textliner&)r_r|r}r'r^_s&       zCommandLine._generate_argsrr)configoptionsr c sj\}}}z0||ffdd|Dfdd|DWnBtjk r~}z"jrZntjt|f|jW5d}~XYnXdS)Ncsg|]}t|dqSr>rSrkrr&r'r]sz'CommandLine.run_cmd..csi|]}|t|dqSr>rrrr&r' ^sz'CommandLine.run_cmd..)rrrKZraiseerrerrrr-)r%rrr_rarer&rr'run_cmdWs zCommandLine.run_cmdOptional[Sequence[str]])argvr cCsF|j|}t|ds$|jdnt|j|j|d}|||dS)Nrztoo few arguments)rrr)r` parse_argshasattrerrorrrr<r)r%rrcfgr&r&r'mainfs  zCommandLine.main)N)N)rTrUrVr(r^rrr&r&r&r'r\[s yr\rrJrr)rr]rbr cKst|dj|ddS)z(The console runner function for Alembic.r)rN)r\r)rr]rbr&r&r'rusr__main__)NN) __future__rargparserr configparserrrr2rXtypingrrrr r r r r rtyping_extensionsrr0rrrrrrPr\rrTr&r&r&r's@                  >