gddlmZddlmZddlZddlZddlZddlZddlZddl m Z ddl m Z ddl m Z ddl mZddl mZdd l mZdd l mZdd l mZdd l mZdd l mZddl mZddl mZddlmZddlmZddlmZddlmZddlmZddlmZer*ddlmZddlm Z ddlm!Z!ddl"m#Z#ddl"m$Z$ddl%m&Z&ddl%m'Z' ejPr ddl)m*Z*dd l)m+Z+n ddl,m*Z*dd l,m+Z+ej\d!Z/ej\d"Z0ej\d#Z1ej\d$Z2d%Z3ej\d&Z4ej\d'Z5Gd(d)Z6Gd*d+ejBZ7y#e-$rdZ*YwxYw),) annotations)contextmanagerN) ModuleType)Any)cast)Iterator)List)Mapping)Optional)Sequence)Set)Tuple) TYPE_CHECKING)Unionrevision) write_hooks)util) migration)compat)not_none) _GetRevArg) _RevIdType)Revision)Config)MessagingOptions) RevisionStep) StampStep)ZoneInfo)ZoneInfoNotFoundErrorz (?!\.\#|__init__)(.*\.py)(c|o)?$z(?!\.\#|__init__)(.*\.py)$z([a-f0-9]+)\.py$z\w+z%(rev)s_%(slug)sz , *|(?: +)z , *|(?: +)|\:c <eZdZdZedddddddedejf d"dZe d#dZ ejd$d Z d%d Z ed&d Ze d' d(d Z d) d*d Zd+dZd,dZd-dZ d.dZ d/dZd0dZd1dZd0dZd1dZ d2dZ d3dZ d4dZd5dZe d#dZ d6dZ!d7dZ"d8dZ#d9dZ$ d: d;d Z% dB!$.$001E1EF  &+F(,yybgg&##"$&GGOOC$89 'cj|j}t|dkDrtjd|dS)Nrz"Multiple version_locations presentr)_version_locationslenrr8)r;locs r<versionszScriptDirectory.versionsps3%% s8a<##$HI Iq6Mr>cH|jrJ|jDcgc]4}tjjt j |6c}Stjjtjj |jdfScc}w)NrC)r*r5r9r:rcoerce_resource_to_filenamejoinr()r;locations r<r@z"ScriptDirectory._version_locationsxs{  ! !!% 6 6 6H @ @ JK 6  GGOOBGGLL:$FGI I s9Bc#dK|jr9|jDcgc]#}tjj |r|%}}n |j g}t }|D]}tj||D]}tjj|}||vrtjd|z?|j|tjj|}tjj|}tj|||}||ycc}ww)NzJFile %s loaded twice! ignoring. Please ensure version_locations is unique.)r*r@r5r9existsrCsetScript _list_py_dirrealpathrwarnaddbasenamedirname_from_filename) r;verspathsdupes file_path real_pathfilenamedir_namescripts r<r/zScriptDirectory._load_revisionss  ! !!333D77>>$'3  ]]OED#00t< GG,,Y7 %II79BC )$77++I677??95..tXxH> =sD0(D+C+D0c |jd}|tjd|jd}| t|}nd}|jd}|ru|jd}dddtj d d d } ||}|t j|} n1|j|D cgc]} | r| j} } nd} |jd } | r/ttj| tjdd|jddk(} ttj ||jdt"||jddk(|jdd| |jd|j%di| |j& Scc} w#t$r} td |z| d} ~ wwxYw)zProduce a new :class:`.ScriptDirectory` given a :class:`.Config` instance. The :class:`.Config` need only have the ``script_location`` key present. script_locationNz0No 'script_location' key found in configuration.r+r*version_path_separator  :;)Nspacenewliner5r`raza'%s' is not a valid value for version_path_separator; expected 'space', 'newline', 'os', ':', ';'prepend_sys_pathrr3truer)r,r-r&r1post_write_hooks) r)r+r,r-r*r1r2r3r4)get_main_optionrr8intr5pathsep_split_on_space_commasplitstripKeyError ValueErrorlist_split_on_space_comma_colonsysr9r$rE_default_file_template get_sectionr4)clsconfigr\tslr+version_locations_strr] split_on_path split_charr*xkerdrvls r< from_configzScriptDirectory.from_configs!001BC  "##E $$%;< ?#&s8 #' & 6 67J K %+%;%;(& " jj M ,9*- %(=(C(C-)% "7!@%(head_arg)s' to narrow to a specific head, or 'heads' for all heads)head_argheadsz(Can't locate revision identified by '%s'r)rRangeNotAncestorErrorrrlowerupperrr8 MultipleHeadsargumentformat_as_commarResolutionError RevisionErrorargs) r;ancestormultiple_headsrr resolutionrnamhreerrs r<_catch_revision_errorsz&ScriptDirectory._catch_revision_errorssE# : -- 7}S#)),{3 *J E#">>H##H-3 6%% <!J,.2;;--bhh7/N##N3 ;'' 8!GKK ##J/R 7%% :##CHHQK0c 9 :sJE EEAA66E A CE/'DE,#EEEc#K|j||5|jj||ddD]}tt| dddy#1swYyxYww)a-Iterate through all revisions. :param base: the base revision, or "base" to start from the empty revision. :param head: the head revision; defaults to "heads" to indicate all head revisions. May also be "head" to indicate a single head revision. rTF) inclusiveassert_relative_lengthN)rr0iterate_revisionsrrK)r;baseheadrevs r<walk_revisionszScriptDirectory.walk_revisions"s^ ( (t ( >((::dd5;63''? > >sA#7A A#A A#c|j5tttdf|jj |cdddS#1swYyxYw)zReturn the :class:`.Script` instance with the given rev identifier, symbolic name, or sequence of identifiers. .N)rrrrKr0 get_revisionsr;id_s r<rzScriptDirectory.get_revisions5sD  ( ( *fck"!!//4+ * *s 2A  Ac|j5ttt|jj |cdddS#1swYyxYwN)rrr rKr0_get_all_currentrs r<get_all_currentzScriptDirectory.get_all_current@s9  ( ( *F T%6%6%G%G%LM+ * *s 0A  Ac|j5tt|jj |cdddS#1swYyxYw)zReturn the :class:`.Script` instance with the given rev id. .. seealso:: :meth:`.ScriptDirectory.get_revisions` N)rrrKr0 get_revisionrs r<rzScriptDirectory.get_revisionDs7 ( ( * 1 1 > >s CD+ * *s )AA c|j5|jj|\}}dddsy|dk(r|S|dS#1swYxYw)z[Convert a symbolic revision, i.e. 'head' or 'base', into an actual revision number.Nrr)rr0_resolve_revision_number)r;rr branch_names r<as_revision_numberz"ScriptDirectory.as_revision_numberPsV  ( ( *#00II#N C+ G^Jq6M+ *s AAc httt|jj||fi|S)aIterate through script revisions, starting at the given upper revision identifier and ending at the lower. The traversal uses strictly the `down_revision` marker inside each migration script, so it is a requirement that upper >= lower, else you'll get nothing back. The iterator yields :class:`.Script` objects. .. seealso:: :meth:`.RevisionMap.iterate_revisions` )rrrKr0r)r;rrkws r<rz!ScriptDirectory.iterate_revisionsas6* V  /D   / /u C C  r>c|jd5|jjcdddS#1swYyxYw)aGReturn the current head revision. If the script directory has multiple heads due to branching, an error is raised; :meth:`.ScriptDirectory.get_heads` should be preferred. :return: a string revision number. .. seealso:: :meth:`.ScriptDirectory.get_heads` z}The script directory has multiple heads (due to branching).Please use get_heads(), or merge the branches using alembic merge.rN)rr0get_current_headr;s r<rz ScriptDirectory.get_current_head{s@ ( (!) $$557   s 7Ac@t|jjS)aUReturn all "versioned head" revisions as strings. This is normally a list of length one, unless branches are present. The :meth:`.ScriptDirectory.get_current_head()` method can be used normally when a script directory has only one head. :return: a tuple of string revision numbers. )ror0rrs r< get_headszScriptDirectory.get_headssD%%++,,r>cx|j}t|dkDrtjd|r|dSy)a#Return the "base" revision as a string. This is the revision number of the script that has a ``down_revision`` of None. If the script directory has multiple bases, an error is raised; :meth:`.ScriptDirectory.get_bases` should be preferred. rz@The script directory has multiple bases. Please use get_bases().rN) get_basesrArr8)r;basess r<get_basezScriptDirectory.get_basesD  u:>##* 8Or>c@t|jjS)zreturn all "base" revisions as strings. This is the revision number of all scripts that have a ``down_revision`` of None. )ror0rrs r<rzScriptDirectory.get_basessD%%++,,r>c|jd|5|j||d}tt|Dcgc],}tj j |j|.c}cdddScc}w#1swYyxYw)NzFDestination %(end)s is not a valid upgrade target from current head(s)rrT) implicit_base)rrreversedror MigrationStepupgrade_from_scriptr0r; destination current_revrevsrZs r< _upgrade_revszScriptDirectory._upgrade_revss ( (*) ))[*D'tDz2 3F'';;%%v3     s+B1A<0B<BB c|jd|5|j||d}|Dcgc],}tjj |j |.c}cdddScc}w#1swYyxYw)NzHDestination %(end)s is not a valid downgrade target from current head(s)rT)select_for_downgrade)rrrrdowngrade_from_scriptr0rs r<_downgrade_revszScriptDirectory._downgrade_revss ( (*) ))*D# #F''==%%v#     sA/1A*A/*A//A8cN|jd5|j|}g}|sd}g}tj|D]G}|s|j |j j ttt||dItj|}|j|xsdg}|D]}|K|j |D cgc]/} tj| jddd|j 1c} Q||vrVt|j j|g} t|j j!|g} | j#|rl| j#|rJ|D cgc]} | j} } tj| |jdd|j } |j%| | j#|rY|D cgc]} | j} } tj| |jdd|j } |j%| tjd|jdd|j } |j%| |cdddScc} wcc} wcc} w#1swYyxYw)NzCMultiple heads are present; please specify a single target revisionrrT)include_dependenciesF)rrrto_tupleextendr0filter_for_lineagerr rK unique_listrr rrJ_get_descendant_nodes_get_ancestor_nodes intersectionappend)r;rr heads_revsstepsfiltered_headsrdestsdestr descendants ancestors todo_headssteps r< _stamp_revszScriptDirectory._stamp_revss ( (%) ++E2JE!+-N}}X."))))<< &!1:>15=/"--n=N&&x0:TFE<LL)7 )7&// $ $ % $ $ 1 1 )7  ^+"%%;;TFC   1 1 E Etf MN ++N; )55nEEEBJ JJ$cDtj|jdy)zRun the script environment. This basically runs the ``env.py`` script present in the migration environment. It is called exclusively by the command functions in :mod:`alembic.command`. env.pyN)rload_python_filer(rs r<run_envzScriptDirectory.run_envAs dhh1r>ctjjtjj|jdS)Nr)r5r9r:rFr(rs r<env_py_locationzScriptDirectory.env_py_locationLs(wwrww||DHHh?@@r>c tjdtjj |fi|j 5tj |||jfi|dddy#1swYyxYwNz Generating )rstatusr5r9r:r4template_to_filer-)r;srcrrs r<_generate_templatez"ScriptDirectory._generate_templatePsc [["''//$/0 1 595H5H   ! !#tT-A-A HR H   s #A--A6ctjdtjj |fi|j 5t j||dddy#1swYyxYwr)rrr5r9r:r4shutilcopy)r;rrs r< _copy_filezScriptDirectory._copy_fileVsT [["''//$/0 1 595H5H  KKT "   s A!!A*ctjj|}tjj|sBt j d|fi|j 5tj|dddyy#1swYyxYw)NzCreating directory )r5r9r:rIrrr4makedirs)r;r9s r<_ensure_directoryz!ScriptDirectory._ensure_directory\spwwt$ww~~d#%dV,040C0C D!$s "BB c8|jttjd t|j}|$ t|jj }t j jjt jjj|}|St j j}|S#t$rd}YwxYw#t$r$tjd|jzdwxYw)NzePython >= 3.9 is required for timezone support or the 'backports.zoneinfo' package must be installed.zCan't locate timezone: %s)tzinfo) r1r!rr8r"rdatetimeutcnowreplaceutc astimezonenow)r;r create_dates r<_generate_create_datez%ScriptDirectory._generate_create_dateds == $''J  !$--0~ %dmm&9&9&;vr|n |j#}}}dddnd}|j@t$j&jC|jDd|ftG|tjHtKd| Dt jL|tjH| tjN||ndd||jP}|rtSjT|| tjW||}|y|r?|j>s3t j d|jd|d|j&d|jjY||S#tj$r(} t j | j d| d} ~ wwxYw#1swYxYwcc}wcc}}w#1swYxYw#tj$r(} t j | j d| d} ~ wwxYw)aGenerate a new revision file. This runs the ``script.py.mako`` template, given template arguments, and creates a new file. :param revid: String revision id. Typically this comes from ``alembic.util.rev_id()``. :param message: the revision message, the one passed by the -m argument to the ``revision`` command. :param head: the head revision to generate against. Defaults to the current "head" if no branches are present, else raises an exception. :param splice: if True, allow the "head" version to not be an actual head; otherwise, the selected head must be a head (e.g. endpoint) revision. Nrrz{Multiple heads are present; please specify the head revision on which the new revision should be based, or perform a merge.rr.rz"Duplicate head revisions specifiedrzAMultiple version locations present, please specify --version-pathz7Path %s is not represented in current version locationszeRevision %s is not a head revision; please specify --splice to create a new branch from this revisionzscript.py.makoc3<K|]}| |jndywrr).0hs r< z4ScriptDirectory.generate_revision..sKUAMajjt;Usz empty message) up_revision down_revision branch_labels depends_onrcommamessagezVersion z specified branch_labels z, however the migration file zb does not have them; have you upgraded your script.py.mako to include the 'branch_labels' section?)-rK verify_rev_idrrrr8rrrrr r0rrArJrr@ isinstancer5r9rQrCnormpathr:r*r _rev_pathis_headto_listrrrrrFr(strtuple_rev_as_scalartuplerrr2r _run_hooks _from_path add_revision)r;revidrrsplicer version_pathrrrrrrhead_ norm_path vers_pathr9deprresolved_depends_onrfrZs r<generate_revisionz!ScriptDirectory.generate_revisions[8 <D :   ' ( (&) hz*C/0!!//5EF{"{  s5z?c%j (##$HI I002  4**+a/"E()%888')wwuzz'B  # ++8 $}} GG$$RWW__\%BC 00Iww *i71##$&23   ! !  " "< 0~~lE7KH$U]]++M..) ,,.$(<< #;%#;C"$"3"3"@"@"EFL#;% ' %S#"3"33 \\*% $ '/.#'  GGLL#3 4  E "66KUKK-- 6334GH#&&&2G   ++   " "4)9 : :&&tT2F > !5!5## ??M6;; @  &&v. a%% :##CHHQK0c 9 :  F% '/.H%% :##CHHQK0c 9 :skP AQ.QQ-Q Q&Q7QQ, Q#P??QQ QQ),R'?#R""R'c  t|j}djtj |xsdj }t ||jkDr%|d|jjddddz}d|j||||j|j|j|j|j|jd zz}t j"j||S)N_rrz%s.py) rslugepochyearmonthdayhourminutesecond)rh timestamprF_slug_refindallrrAr+rsplitr)rrr r!r"r#r5r9)r;r9rev_idrrrrrXs r<rzScriptDirectory._rev_pathsK))+,xx((B78>>@ t9t00 03$334;;CCAFLD   #(($**"#((%,,%,,    ww||D(++r>)r(r r)r r+z Optional[int]r*zOptional[List[str]]r,boolr-r r1 Optional[str]r2zOptional[Mapping[str, str]]r3r)r4rreturnNoner+r )r+z Sequence[str])r+Iterator[Script])rurr+r$)NNNNN) rr*rr*rr*rr*rr*r+zIterator[None])rr)rr rr r+r.)rrr+zTuple[Script, ...])rzTuple[str, ...]r+z Set[Script])rr r+rK)rr*r+z%Optional[Union[str, Tuple[str, ...]]])r!Union[str, Tuple[str, ...], None]rr/rrr+r.)r+r*)r+ List[str])rr rr r+List[RevisionStep])rr rr*r+r1)rrrrr+zList[StampStep])r+r,)rr rr rrr+r,)rr rr r+r,)r9r r+r,)r+datetime.datetime)NFNNN)rr rr*rOptional[_RevIdType]rOptional[bool]rr3rr*rr3rrr+Optional[Script]) r9r r(r rr*rr2r+r )'__name__ __module__ __qualname____doc__rrrr EMPTY_DICTr=propertyrCmemoized_propertyr@r/ classmethodr}rrrrrrrrrrrrrrrrrrrrrrrrr>r<r$r$:s,4.015 &"&37,1+/ ,     ,  /      1 &* )   D JJ:R R h#'(,#!$( +:+:&+: +:  +: " +: +:+:\/6(((+( (& N E  ." 0 1     480 -,--0 $-: $\"\+5\ \| 2AAI # "@&*!&.2&*+/QQQ# Q  Q , Q$Q)QQ Qf,,, , ' , ,r>r$c8eZdZUdZdfd Zded< ded< dZded < edd Zedd Z edd Z dd Z d ddZ d ddZ ddZe ddZeddZe ddZxZS)rKzRepresent a single revision file in a ``versions/`` directory. The :class:`.Script` instance is returned by methods such as :meth:`.ScriptDirectory.iterate_revisions`. modulerr r9c ||_||_t| ||jt j t|dddt j t|dddy)Nrr)defaultr)r dependencies)r?r9superr=rrrgetattr)r;r?r(r9 __class__s r<r=zScript.__init__7se      --6 d3R  r>Nr4_db_current_indicatorcHtjd|jdS))Return the docstring given in the script.z r)rrklongdocrs r<docz Script.docOsxx -a00r>c|jj}|rKt|jdr%|j|jj}|j Sy)rH_alembic_source_encodingr)r?r9hasattrdecoderLrl)r;rJs r<rIzScript.longdocUsQkk!! t{{$>?jjKK8899; r>cd|j|jrdnd|jrdnd|jrdnd|jrdndd}|jr|d|j dz }n|d |j dz }|j r%|d tj|j zz }|jr%|d tj|jzz }|jr&|d tj|jdz }|d |jdz }|ddjd|jjDzz }|S)NzRev:  (head)r (branchpoint) (mergepoint) (current)r_zMerges: zParent: zAlso depends on: %s zBranches into: %s zBranch names: zPath: z %s c3&K|] }d|z yw)z %sNr)rparas r<rz#Script.log_entry..sL2K$ho2Ks)rris_branch_pointis_merge_pointrF_format_down_revisionrBrrnextrevrr9rFrI splitlines)r;entrys r< log_entryzScript.log_entrycs^ MMI2 - $ 4 4 " <#22O : 66LB >      t'A'A'CE EE t'A'A'CE EE    ,$$T%6%67 E    *$$T\\2 E    $$T%7%78 E ,,  IIL$,,2I2I2KL L   r>c|jd|j|jrdnd|jrdnd|jrdndd|j S)N -> rPrrQrRz, )rXrrrVrWrJrs r<__str__zScript.__str__sU  & & ( MMI2 - $ 4 4 " <#22O : HH   r>c>|j}|rW|jr6|jdtj|jd|}n|jd|}|J|r1|j r%|dtj|j zz }|s|rA||j rdnd|jr|j sdnd|jrdndz }|r%||jrd nd|jrd ndz }|r|d |jzz }|S) Nz (z) -> r^z (%s)rPrz (effective head)rSrQrRz, %s) rrBrXrrr _is_real_headrrFrVrWrJ)r;include_branches include_docinclude_parentstree_indicatorshead_indicatorstexts r< _head_onlyzScript._head_onlys5}}   ..0(():):; &*%?%?%A4H  2 2 Gd2243E3EFF FD o !// R7||D,>,>(!% : : B D  $($8$8 b@#'#6#6B> D  FTXX% %D r>cF|r |jS|j||||Sr)r\rh)r;verboserbrcrdres r< cmd_formatzScript.cmd_formats+ >> !?? + r>cZ|jsytj|jS)Nz)rrr_versioned_down_revisionsrs r<rXzScript._format_down_revisions%!!''(F(FG Gr>cltjj|\}}|j|||Sr)r5r9rkrR)rt scriptdirr9dir_rXs r<rzScript._from_paths/t,h!!)T8<cr g}tj|dD]\}}}|jdrt|D]1}|j tj j ||3|jrtj j |d tj j rP|Dchc]}|jddc}|j fdtj D|js|S|j|Scc}w)NT)topdown __pycache__.rc3K|]:}|jddvr"tjj|<yw)rtrN)rkr5r9rF)rpycnames py_cache_paths r<rz&Script._list_py_dir..s=!#!,E9 ]C8#>-0EJJEX^^C03EJELL!#%::m#<! 88  IIK="=@ !KsD4cN|jrtj|}ntj|}|sy|j d}|jr)|j ddk(}|j ddk(}ndx}}|s|rt j jt j j||}t j jt j j||dz} |s|r| rytj||} t| dsAtj|} | stjd|z| j d} n | j} t| | t j j||S)NrrcoFrzCould not determine revision id from filename %s. Be sure the 'revision' variable is declared inside the script (please see 'Upgrading from Alembic 0.1 to 0.2' in the documentation).)r,_sourceless_rev_filematch_only_source_rev_filegroupr5r9rIrFrrrM _legacy_revr8rrK) rtrorprXpy_match py_filenameis_cis_o py_exists pyc_existsr?mrs r<rRzScript._from_filenames\   +11(;H,228>!$+D>>!$+D D4 4rww||D+'FGI T;;L(MNJ DZ&&tX6vz*!!(+A''F 771:Hfh T8(DEEr>)r?rr(r r9r r-)FFFTT) rbr)rcr)rdr)rer)rfr)r+r )FFFT) rjr)rbr)rcr)rdr)rer)r+r )ror$r9r r+r5)ror$r9r r+r0)ror$rpr rXr r+r5)r6r7r8r9r=__annotations__rFr;rJrIr\r_rhrkrXr=rrLrR __classcell__)rEs@r<rKrK/s   B I(,0>0411   !!F "'! % $ $ &&& &  &  & &V"'! % $          H ='=/2= == ""H/F'/F/2/F>A/F /F/Fr>rK)8 __future__r contextlibrrr5rrrqtypesrtypingrrrr r r r r rrrrrrrruntimerrrrrrrurrruntime.migrationrr py39zoneinfor!r"backports.zoneinfo ImportErrorcompilerrrr%rrrjrpr$rKrr>r<rs*"%  $$")0- {{%2/<"rzz"EF" #@Abjj,- 2::f +" =1(bjj)9:r ,r ,j{FX  {FEHs:%E--E76E7