|L iMddlmZddlmZddlmZddlZddlZddlmZddlm Z ddlm Z ddlm Z dd lm Z dd lm Z dd lmZdd lmZdd lmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlm Z ddl!m"Z"ddl!m#Z#ddl#m$Z$ddl%m&Z&erNddlm'Z'ddlm(Z(dd l)m*Z*dd!l)m+Z+dd"l,m-Z-dd#l.m/Z/d$d%l0m1Z1dd&l2m3Z3dd'l4m5Z5dd(l4m6Z6dd)l7m8Z8dd*l7m9Z9dd+l7m:Z:ejve<Z=Gd,d-Z>Gd.d/Z?Gd0d1Z@Gd2d3ZAGd4d5ZBGd6d7eBZCGd8d9eBZDy):) annotations)contextmanager) nullcontextN)Any)Callable)cast) Collection)Dict)Iterable)Iterator)List)Optional)Set)Tuple) TYPE_CHECKING)Union)Column)literal_column)select)Engine)url)MockEngineStrategy)ContextManager)ddl)util) sqla_compat) EncodedIO)Dialect)URL) Connection) Transaction)MockConnection) Executable)EnvironmentContext)Config)Script)ScriptDirectory)_RevisionOrBase)Revision) RevisionMapcFeZdZddZed dZd dZd dZd dZd dZ y) _ProxyTransactionc||_yN)migration_context)selfr1s _/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/alembic/runtime/migration.py__init__z_ProxyTransaction.__init__9s !2c.|jjSr0)r1 _transactionr2s r3_proxied_transactionz&_ProxyTransaction._proxied_transaction<s%%222r5cf|j}|J|jd|j_yr0)r9rollbackr1r7r2ts r3r;z_ProxyTransaction.rollback@s.  % %}} .2+r5cf|j}|J|jd|j_yr0)r9commitr1r7r<s r3r?z_ProxyTransaction.commitFs.  % %}}  .2+r5c|Sr0r8s r3 __enter__z_ProxyTransaction.__enter__Ls r5cz|j/|jj|||d|j_yyr0)r9__exit__r1r7)r2type_value tracebacks r3rDz_ProxyTransaction.__exit__Os9  $ $ 0  % % . .ueY G26D " " / 1r5N)r1MigrationContextreturnNone)rIzOptional[Transaction])rIrJ)rIr.)rErrFrrGrrIrJ) __name__ __module__ __qualname__r4propertyr9r;r?rBrDrAr5r3r.r.8s/3333 3 7r5r.cFeZdZdZ d ddZe d ddZeddZ d ddZ ddZ ddZ ddd Z dd Z dd Zd d Zdd Z d d!dZ d"dZed#dZed$dZ d%dZ d&dZy)'rHaRepresent the database state made available to a migration script. :class:`.MigrationContext` is the front end to an actual database connection, or alternatively a string output stream given a particular database dialect, from an Alembic perspective. When inside the ``env.py`` script, the :class:`.MigrationContext` is available via the :meth:`.EnvironmentContext.get_context` method, which is available at ``alembic.context``:: # from within env.py script from alembic import context migration_context = context.get_context() For usage outside of an ``env.py`` script, such as for utility routines that want to check the current version in the database, the :meth:`.MigrationContext.configure` method to create new :class:`.MigrationContext` objects. For example, to get at the current revision in the database using :meth:`.MigrationContext.get_current_revision`:: # in any application, outside of an env.py script from alembic.migration import MigrationContext from sqlalchemy import create_engine engine = create_engine("postgresql://mydatabase") conn = engine.connect() context = MigrationContext.configure(conn) current_rev = context.get_current_revision() The above context can also be used to produce Alembic migration operations with an :class:`.Operations` instance:: # in any application, outside of the normal Alembic environment from alembic.operations import Operations op = Operations(context) op.alter_column("mytable", "somecolumn", nullable=True) Nc||_||_||_|jd|_|jdd}|jd}|jdd|_|jdd|_d|_|r=ttd|j||_ |jJd|_ n!||_ tj||_ |jd |_||_|jd d|_d |vr6t%|jd xst&j(|d |_n%|jd t&j(|_||_|jd d|_|jdd|_|jddx|_}|jddx|_}|jd|_t9j:j=|||j|j ||j*||_|j>jA|||jdd|_!tDjGd|j>jHjJ|j rtDjGdtDjGd|j>j,rdydy)Nscriptas_sqlFtransactional_ddltransaction_per_migrationon_version_applyrAr!fnpurgeoutput_encoding output_buffer compare_typeTcompare_server_default version_tablealembic_versionversion_table_schema starting_revversion_table_pk)r\r^r`zContext impl %s.zGenerating static SQLzWill assume %s DDL. transactionalznon-transactional)&environment_contextoptsdialectgetrQ_transaction_per_migrationon_version_apply_callbacksr7rr_stdout_connection connection_in_external_transactionr_get_connection_in_transaction_migrations_fnrRrWrsysstdoutrYrS_user_compare_type_user_compare_server_defaultr\r^_start_from_revr DefaultImplget_by_dialectimplversion_table_impl_versionloginfo __class__rK) r2rdrircrbrRrSr\r^s r3r4zMigrationContext.__init__s$7   15(1C xx%0 HH%89*.(( '+ '+/((3Er*J'37 "&(?(? (KDO??. ..,1D )(DO:::F  ) HHTN  XXgu-  $!*)::&'"D  "&"D "3"&((>4"@,0HH $e- ).2XX ..  ]<@88 "D<  !$8/3hh~.FOO227;  OO KK         44'!5!XX&8$?5  #TYY%8%8%A%AB ;; HH, -  !99..  )  r5c||i}|i}|r5t|trtjd|z|j}nl|r,t j |}|jdi|}n>|r/t j d|z}|jdi|}n |s td|Jt||||S)aCreate a new :class:`.MigrationContext`. This is a factory method usually called by :meth:`.EnvironmentContext.configure`. :param connection: a :class:`~sqlalchemy.engine.Connection` to use for SQL execution in "online" mode. When present, is also used to determine the type of dialect in use. :param url: a string database url, or a :class:`sqlalchemy.engine.url.URL` object. The type of dialect to be used will be derived from this if ``connection`` is not passed. :param dialect_name: string name of a dialect, such as "postgresql", "mssql", etc. The type of dialect to be used will be derived from this if ``connection`` and ``url`` are not passed. :param opts: dictionary of options. Most other options accepted by :meth:`.EnvironmentContext.configure` are passed via this dictionary. zf'connection' argument to configure() is expected to be a sqlalchemy.engine.Connection instance, got %rz%s://z-Connection, url, or dialect_name is required.rA) isinstancerr CommandErrorrdsqla_urlmake_url get_dialect ExceptionrH) clsrir dialect_namerdrb dialect_optsrcurl_objs r3 configurezMigrationContext.configures> <D  L *f-'')* !((G '',G+g))+;l;G '',(>?G+g))+;l;GKL L"""T;NOOr5c#ZK|j}|jjr'|jr|jj n1|r/|j J|j j d|_|jsw|jJ|jj}|j}|jdx|_|j_|jj}nd} d|jsT|jJ||j |jjx|_|j_|jjr'|jr|jjy|r.|jJ|jj|_yy#|jsT|jJ||j |jjx|_|j_|jjr'|jr|jjw|r.|jJ|jj|_wwxYww)aLEnter an "autocommit" block, for databases that support AUTOCOMMIT isolation levels. This special directive is intended to support the occasional database DDL or system operation that specifically has to be run outside of any kind of transaction block. The PostgreSQL database platform is the most common target for this style of operation, as many of its DDL operations must be run outside of transaction blocks, even though the database overall supports transactional DDL. The method is used as a context manager within a migration script, by calling on :meth:`.Operations.get_context` to retrieve the :class:`.MigrationContext`, then invoking :meth:`.MigrationContext.autocommit_block` using the ``with:`` statement:: def upgrade(): with op.get_context().autocommit_block(): op.execute("ALTER TYPE mood ADD VALUE 'soso'") Above, a PostgreSQL "ALTER TYPE..ADD VALUE" directive is emitted, which must be run outside of a transaction block at the database level. The :meth:`.MigrationContext.autocommit_block` method makes use of the SQLAlchemy ``AUTOCOMMIT`` isolation level setting, which against the psycogp2 DBAPI corresponds to the ``connection.autocommit`` setting, to ensure that the database driver is not inside of a DBAPI level transaction block. .. warning:: As is necessary, **the database transaction preceding the block is unconditionally committed**. This means that the run of migrations preceding the operation will be committed, before the overall migration operation is complete. It is recommended that when an application includes migrations with "autocommit" blocks, that :paramref:`.EnvironmentContext.transaction_per_migration` be used so that the calling environment is tuned to expect short per-file migrations whether or not one of them has an autocommit block. N AUTOCOMMIT)isolation_level) _in_connection_transactionrtrSrR emit_commitr7r?riget_isolation_levelexecution_optionsbegin emit_begin)r2r current_levelbase_connection fake_transs r3autocommit_blockz!MigrationContext.autocommit_blocks7Z&*%D%D%F" 99 & &4;; II ! ! # '$$0 00    $ $ & $D {{??. .. OO??AM"ooO 11,1O DOdii2 150E0E0GJJ < ;;222)%%'11$12:IH$))"6yy**t{{ $$&+222$(OO$9$9$;!,;;222)%%'11$12:IH$))"6yy**t{{ $$&+222$(OO$9$9$;!,s DJ+G CJ+CJ((J+cfjr tSjjr|jk(}n|du}|s tSjjsq|sJj r tSj du}|r tSjJtjj_tSj rtfd}|SjJtjj_tS)aBegin a logical transaction for migration operations. This method is used within an ``env.py`` script to demarcate where the outer "transaction" for a series of migrations begins. Example:: def run_migrations_online(): connectable = create_engine(...) with connectable.connect() as connection: context.configure( connection=connection, target_metadata=target_metadata ) with context.begin_transaction(): context.run_migrations() Above, :meth:`.MigrationContext.begin_transaction` is used to demarcate where the outer logical transaction occurs around the :meth:`.MigrationContext.run_migrations` operation. A "Logical" transaction means that the operation may or may not correspond to a real database transaction. If the target database supports transactional DDL (or :paramref:`.EnvironmentContext.configure.transactional_ddl` is true), the :paramref:`.EnvironmentContext.configure.transaction_per_migration` flag is not set, and the migration is against a real database connection (as opposed to using "offline" ``--sql`` mode), a real transaction will be started. If ``--sql`` mode is in effect, the operation would instead correspond to a string such as "BEGIN" being emitted to the string output. The returned object is a Python context manager that should only be used in the context of a ``with:`` statement as indicated above. The object has no other guaranteed API features present. .. seealso:: :meth:`.MigrationContext.autocommit_block` TNc3~Kjjdjjywr0)rtrrr8sr3 begin_commitz8MigrationContext.begin_transaction..begin_commits* $$& %%'s:=) rjrrtrSrfrRr7rir"_safe_begin_connection_transactionr.r)r2_per_migrationtransaction_nowin_transactionrs` r3begin_transactionz"MigrationContext.begin_transactionusX  ( (= 99 & &,0O0OOO,4O= ,,! !>{{"}$"&!2!2$!>!&=(??666#FF OO% -T22 [[  ( (  > !??. .. + N N!D %T* *r5c|j}t|dk(ryt|dkDr"tjd|jz|dS)aReturn the current revision, usually that which is present in the ``alembic_version`` table in the database. This method intends to be used only for a migration stream that does not contain unmerged branches in the target database; if there are multiple branches present, an exception is raised. The :meth:`.MigrationContext.get_current_heads` should be preferred over this method going forward in order to be compatible with branch migration support. If this :class:`.MigrationContext` was configured in "offline" mode, that is with ``as_sql=True``, the ``starting_rev`` parameter is returned instead, if any. rNr%zQVersion table '%s' has more than one head present; please use get_current_heads())get_current_headslenrr|r\r2headss r3get_current_revisionz%MigrationContext.get_current_revisions] &&( u:? Z!^##1373E3EF  8Or5cL|jr|j}|dk(rd}nW|U|jrItj|Dcgc]+}|dvr%|jj |j -}}tj|dS|jrtjd|jsy|jJtd|jjt|jjj DScc}w)aReturn a tuple of the current 'head versions' that are represented in the target database. For a migration stream without branches, this will be a single value, synonymous with that of :meth:`.MigrationContext.get_current_revision`. However when multiple unmerged branches exist within the target database, the returned tuple will contain a value for each head. If this :class:`.MigrationContext` was configured in "offline" mode, that is with ``as_sql=True``, the ``starting_rev`` parameter is returned in a one-length tuple. If no version table is present, or if there are no revisions present, an empty tuple is returned. baseN)NrrAdefaultzECan't specify current_rev to context when using a database connectionc3&K|] }|d yw)rNrA).0rows r3 z5MigrationContext.get_current_heads..s  F s)rRrqrQrto_list get_revisionrevisionto_tupler|_has_version_tableritupleexecuterrvc version_num)r2start_from_revsfrs r3rz"MigrationContext.get_current_headss $ ;;"&"6"6N'!%+  $||N;".0KK,,S1::"" ==< <##''7**,*** ..t}}223   "s0D!c\tj|j5|jJ|jj |jd|rA|jJ|jj |jj dddy#1swYyxYw)NT) checkfirst)r_ensure_scope_for_ddlrirvcreaterdelete)r2rWs r3_ensure_version_tablez&MigrationContext._ensure_version_table!s  . .t ? @??. .. MM T B222'' (<(<(>?  @ @ @s A9B""B+c|jJtj|j|j|jSr0)rir_connectable_has_tabler\r^r8s r3rz#MigrationContext._has_version_table)s<***11 OOT//1J1J  r5c|j}|js|s|jt||}|j ||D]}|j |y)a\Stamp the version table with a specific revision. This method calculates those branches to which the given revision can apply, and updates those branches as though they were migrated towards that revision (either up or down). If no current branches include the revision, it is added as a new branch head. N)rrRrHeadMaintainer _stamp_revsupdate_to_step)r2script_directoryrrhead_maintainersteps r3stampzMigrationContext.stamp/s]&&({{5  & & ((u5$005A 1D  * *4 0 1r5c |jj|jr6|jrt j d|j dd}nL|j}|jjdd}|js|s|s|j t||}|jJ|j||D]}|jd5|jr?|js3|jJ|jj!|jt"j%d ||jr(|jj'd |j(|j*di||j-||j.D]+}|||j$t1|j| - ddd|jrA|js4|jJ|jj3|jyyy#1swYmxYw) a-Run the migration scripts established for this :class:`.MigrationContext`, if any. The commands in :mod:`alembic.command` will set up a function that is ultimately passed to the :class:`.MigrationContext` as the ``fn`` argument. This function represents the "work" that will be done when :meth:`.MigrationContext.run_migrations` is called, typically from within the ``env.py`` script of the migration environment. The "work function" then provides an iterable of version callables and other version information which in the case of the ``upgrade`` or ``downgrade`` commands are the list of version scripts to invoke. Other commands yield nothing, in the case that a command wants to run some other operation against the database such as the ``current`` or ``stamp`` commands. :param \**kw: keyword arguments here will be passed to each migration callable, that is the ``upgrade()`` or ``downgrade()`` method within revision scripts. z!Can't use --purge with --sql modeT)rWrA dont_mutateFN)rz Running %sz -- Running )ctxrrrun_args)rtstart_migrationsrWrRrr|rrrcrerrlrrrirvrrwrx static_output short_log migration_fnrrgsetdrop)r2kwrrrrcallbacks r3run_migrationszMigrationContext.run_migrations?s* ""$ ::{{''(KLL  & &T & 2E**,E))-- u=K;;u[**,(u5""...''t4 D''t'< ;;'<'< ??666MM((9t,;;II+++/>>;"!!'B' ..t4 $ ? ?H !YY!/"7"78!# '   8 ;;44??. .. MM  t / 5;7  s +C3H88I c\ |jj}|S#t$rYywxYwNF)rirAttributeError)r2meths r3rz+MigrationContext._in_connection_transactions3 ??11D6M  s  ++c<|jj||y)aExecute a SQL construct or string statement. The underlying execution mechanics are used, that is if this is "offline mode" the SQL is written to the output buffer, otherwise the SQL is emitted on the current SQLAlchemy connection. Nrt_exec)r2sqlrs r3rzMigrationContext.executes ./r5cNfd}tjj|S)Nc<jj|yr0r) construct multiparamsparamsr2s r3dumpz1MigrationContext._stdout_connection..dumps IIOOI &r5)rr#rd)r2rirs` r3rhz#MigrationContext._stdout_connections! '"00tDDr5c|jS)aReturn the current "bind". In online mode, this is an instance of :class:`sqlalchemy.engine.Connection`, and is suitable for ad-hoc execution of any kind of usage described in SQLAlchemy Core documentation as well as for usage with the :meth:`sqlalchemy.schema.Table.create` and :meth:`sqlalchemy.schema.MetaData.create_all` methods of :class:`~sqlalchemy.schema.Table`, :class:`~sqlalchemy.schema.MetaData`. Note that when "standard output" mode is enabled, this bind will be a "mock" connection handler that cannot return results and is only appropriate for a very limited subset of commands. )rir8s r3bindzMigrationContext.binds&r5cH|jr|jjSy)zLReturn the :class:`.Config` used by the current environment, if any.N)rbconfigr8s r3rzMigrationContext.configs"  # #++22 2r5c|jduryt|jr-|j||||j|j}||S|jj ||Sr)rocallabletypertrZ)r2inspector_columnmetadata_column user_values r3 _compare_typezMigrationContext._compare_typest  " "e + D++ ,00  %%$$ J%!!yy%%&6HHr5c|jduryt|jr$|j|||||j|}||S|jj ||||Sr)rprserver_defaultrtr[)r2rrrendered_metadata_defaultrendered_column_defaultrs r3_compare_server_defaultz(MigrationContext._compare_server_defaults|  , , 5 D55 6:: '..) J%!!yy//   % #   r5r0) rdrriOptional[Connection]rczDict[str, Any]rbOptional[EnvironmentContext]rIrJ)NNNNNNN)rirrzOptional[Union[str, URL]]r Optional[str]rdzOptional[Dialect]rbrrzOptional[Dict[str, str]]rcz Optional[Any]rIrH)rIzIterator[None])F)rboolrIz>Union[_ProxyTransaction, ContextManager[None, Optional[bool]]]rIrrITuple[str, ...])rWrrIrJrIr)rr)rstrrIrJrrrIrJ)rzUnion[Executable, str]rzOptional[Dict[str, Any]]rIrJ)rirrIr#)rIr)rIzOptional[Config])r Column[Any]rrrIr) rrrrrrrrrIr)rKrLrM__doc__r4 classmethodrrrrrrrrrrrrrhrNrrrrrAr5r3rHrHUs-h=A X X )X  X : X  X t,0)-&*%)<@15"5P(5P'5P$ 5P # 5P : 5P/5P5P 5P5Pn[<[<|&+b+"b+ Gb+H6+ Z@ 1 F0P7; 0 # 04 0  0E.E E(I +I>DI I& % % $1  "/    r5rHc4eZdZddZddZddZd dZd dZy) rc2||_t||_yr0)contextrr)r2rrs r3r4zHeadMaintainer.__init__s Z r5c ||jvsJ|jj||jjj |jj j jtd|zy)N'%s'r) raddrrtrrvinsertvaluesr)r2versions r3_insert_versionzHeadMaintainer._insert_versionsodjj((( w  LL ! ! ( ( * 1 1*6G+;< 2  r5c Z|jj||jjj |jj j j|jj jjtd|zk(}|jjsm|jjjrL|I|jdk7r9tj d||jj"|jfzyyyy)Nrr%zOOnline migration expected to match one row when deleting '%s' in '%s'; %d found)rremoverrtrrvrwhererrrrRrdsupports_sane_rowcountrowcountrr|r\)r2rrets r3_delete_versionzHeadMaintainer._delete_versions '"ll%% LL ! ! ( ( * 0 0 %%''33!&7"234   ## $$;; !##DLL66 EF " <$r5c ||jvsJ|jj||jj||jjj |jj jjtd|zj|jj jjtd|zk(}|jjsn|jjjrM|J|j dk7r:t#j$d|||jj&|j fzyyyy)Nrrr%zWOnline migration expected to match one row when updating '%s' to '%s' in '%s'; %d found)rrrrrtrrvupdaterrr rrrRrdr r rr|r\)r2from_to_r s r3_update_versionzHeadMaintainer._update_versions0$**$$$ %  sll%% LL ! ! ( ( * Vv| `.)r,r9r+r8s r3r/zMigrationInfo.down_revisionss!  ..t/E/EFFr5cL|jj|jS)zdGet :attr:`~MigrationInfo.source_revision_ids` as a tuple of :class:`Revisions <.Revision>`.)r,r9r3r8s r3source_revisionszMigrationInfo.source_revisionss!  ..t/G/GHHr5cL|jj|jS)ziGet :attr:`~MigrationInfo.destination_revision_ids` as a tuple of :class:`Revisions <.Revision>`.)r,r9r5r8s r3destination_revisionsz#MigrationInfo.destination_revisionss!  ..t/L/LMMr5N) r,r,r'rr(rr.Union[str, Tuple[str, ...]]r/r?rIrJrr)rIzOptional[Revision])rIz%Tuple[Optional[_RevisionOrBase], ...])rKrLrMr__annotations__r4rNr1r3r5r7r.r/r<r>rAr5r3r&r&esBN6"! %$'&AK!KK K 2 K 4 K K*!!    CCEE GG II NNr5r&ceZdZUded<ded<ded<ded<er eddZedd Ze dd Z e dd Z edd Z edd Z dZ y) MigrationSteprfrom_revisions_no_depsto_revisions_no_depsrr'rrcyr0rAr8s r3doczMigrationStep.docs(+r5c.|jjSr0)rrKr8s r3namezMigrationStep.names  )))r5ct||dS)NT RevisionSteprr,rQs r3upgrade_from_scriptz!MigrationStep.upgrade_from_scriptsL&$77r5ct||dSrrJrLs r3downgrade_from_scriptz#MigrationStep.downgrade_from_scriptsL&%88r5c|j Sr0)r'r8s r3 is_downgradezMigrationStep.is_downgrades??""r5c|jdtj|jdtj|jS)N  -> )rHrformat_as_commarCrDr8s r3rzMigrationStep.short_logs= II  !%>?  >> !r5NrrIr)r,r,rQr(rIrKr)rKrLrMr@rrNrFrHrrMrOrQrrWrAr5r3rBrBs++)) + + **8&8068 88 9&9069 99 ##   "r5rBc,eZdZ ddZdZddZeddZeddZe ddZ eddZ e ddZ edd Z dd Z dd Zdd Z dd ZddZddZddZddZed dZed dZed!dZy)"rKc||_||_||_|r|jj|_y|jj |_yr0)r,rr'moduleupgrader downgrade)r2r,rr's r3r4zRevisionStep.__init__sA)  $  ( 7 7D  ( 9 9D r5cPd|jjd|jdS)Nz RevisionStep(z , is_upgrade=))rr'r8s r3__repr__zRevisionStep.__repr__'s MM " " OO  r5ct|txr4|j|jk(xr|j|jk(Sr0)r{rKrr'r2others r3__eq__zRevisionStep.__eq__-s= ul + 4$--/ 45#3#33 r5c.|jjSr0)rrFr8s r3rFzRevisionStep.doc4s}}   r5ct|jr|jjS|jjfSr0r'r_normalized_down_revisionsr8s r3from_revisionszRevisionStep.from_revisions8s, ??==;; ;MM**, ,r5ct|jr|jjS|jjfSr0r'r_versioned_down_revisionsr8s r3rCz#RevisionStep.from_revisions_no_deps?s. ??==:: :MM**, ,r5ct|jr|jjfS|jjSr0rgr8s r3 to_revisionszRevisionStep.to_revisionsHs, ??MM**, ,==;; ;r5ct|jr|jjfS|jjSr0rkr8s r3rDz!RevisionStep.to_revisions_no_depsOs. ??MM**, ,==:: :r5cFt|jjdk(SNr%)rrrhr8s r3_has_scalar_down_revisionz&RevisionStep._has_scalar_down_revisionXs4==;;<AAr5c|jsy|jj|vry|jj}|sy|j|}| S)zA delete is when we are a. in a downgrade and b. we are going to the "base" or we are going to a version that is implied as a dependency on another version that is remaining. FT)rQrrh_unmerge_to_revisions)r2rdownrevsrns r3rz!RevisionStep.should_delete_branch\sU    == ! ! .==;; 55e>%%33K@? I "D''(33I>N"$"5"56N "% & 2    a   sCc t|j|jjg}|rz|jj |jj |dDchc]}|j}}t t|jj|S|jDchc]X}|jj |jj |dD]}|j|k7r |jZ}}}t t|jj|Scc}wcc}}w)NFrw)rrzrr,r{r9rrn)r2rr}r~r to_revisions r3rtz"RevisionStep._unmerge_to_revisionss=%j++T]]-C-C,DE **>>%%33K@? I T../::9EF F$(#4#4**>>%%33K@?::,  IT../::9EF F's *E;AE cT|j|}|jd|d|ddfSNrry)rtri)r2rrns r3rz"RevisionStep.unmerge_branch_identss@11%8     "   2    r5ct|jsy|jj}|sy|j|syy)NFT)r'rrh intersectionr2rrus r3rz!RevisionStep.should_create_branchs7==;; %%h/r5c|jsy|jj}t|dkDrt|j |dkDryyNFr%T)r'rrhrrrs r3rz"RevisionStep.should_merge_branchessD==;; x=1 U%7%7%A!BQ!Fr5c|jsy|jj}|jj|vrt|dkDryyr)rQrrhrrs r3rz$RevisionStep.should_unmerge_branchess@  ==;; == ! !U *s8}q/@r5cV|jsI|j|jj}t |dk(sJdt |d}n|jjd}|j r||jjfS|jj|fS)Nr%z4Can't do an UPDATE because downrevision is ambiguousr)rrrrrhrr|r')r2rdownrev down_revisions r3rzRevisionStep.update_version_nums--(( 88GG ! FE F! M!,M MMDDQGM ?? $--"8"88 8==))=8 8r5c.|jjSr0rr8s r3rzRevisionStep.delete_version_num}}%%%r5c.|jjSr0rr8s r3rzRevisionStep.insert_version_numrr5ct|j|jj|jj|jdS)NFr,r.r/r'r()r&r,rrhr'r8s r3rxzRevisionStep.infos<**//==CC   r5N)r,r,rr(r'rrIrJ)rcobjectrIrrrrrSet[str]rIr)rrrIzTuple[List[str], str, str])rrrIr)rrrIz Tuple[str, str, Tuple[str, ...]]rrrIzTuple[str, str]rXrIr&)rKrLrMr4r`rdrNrFrirCrnrDrrrrrtrrrrrrrrxrAr5r3rKrKs@ :' :39 :GK :  :  !!-- - --<< ; ;;BB$.  # 2G0    )  &  9"&&&&  r5rKceZdZU d ddZdZded<ddZdZedZ eddZ e dd Z e dd Z edd Z edd Zdd Z ddZ ddZddZddZddZddZeddZy) StampStepNctj|d|_tj|d|_||_||_|j |_||_y)NrAr) rrrrr' branch_movestamp_revisionrr,)r2rrr'rr,s r3r4zStampStep.__init__sM'+mmE2&F $(MM#r$B$& //(r5rrFc yr0rA)r2rs r3rzStampStep.stamp_revisionsr5ct|txrj|j|jk(xrO|j|jk(xr4|j|jk(xr|j |j k(Sr0)r{rrirnrr'rbs r3rdzStampStep.__eq__sw ui ( 4$$(;(;; 4""d&7&77 4!!T%5%55 45#3#33  r5c|jSr0rr8s r3rizStampStep.from_revisionss zzr5c|jSr0rr8s r3rnzStampStep.to_revisionss xxr5c|jSr0rr8s r3rCz StampStep.from_revisions_no_deps#szzr5c|jSr0rr8s r3rDzStampStep.to_revisions_no_deps)s xxr5cTt|jdk(sJ|jdSNr%rrrr8s r3rzStampStep.delete_version_num/s&4::!###zz!}r5cTt|jdk(sJ|jdSrrrr8s r3rzStampStep.insert_version_num4s&488}!!!xx{r5ct|jdk(sJt|jdk(sJ|jd|jdfSr)rrrrs r3rzStampStep.update_version_num9sI4::!###488}!!!zz!}dhhqk))r5clt|jdd|jd|jdfSr)r|rrrs r3rzStampStep.merge_branch_idents>s7 Ab! " JJrN HHQK   r5cl|jd|jdt|jddfSr)rrr|rs r3rzStampStep.unmerge_branch_identsHs6 JJqM HHRL !B   r5c6|jxr |jSr0)rQrrs r3rzStampStep.should_delete_branchRs  5T%5%55r5c|jxrX|jxs$t|jj |xr$t|j j |Sr0)r'rrrrzrrs r3rzStampStep.should_create_branchXsO OO 0!!FS_%?%?%F 0DHH ((/ r5c2t|jdkDSrqrrs r3rzStampStep.should_merge_branches_s4::""r5c2t|jdkDSrqrrs r3rz!StampStep.should_unmerge_branchesbs488}q  r5c|jr|j|jfn|j|jf\}}|jJt |j|||jdS)NTr)r'rrr,r&)r2updowns r3rxzStampStep.infoespXXtzz "**dhh' D   ,,,**   r5r0) r%Optional[Union[str, Collection[str]]]rrr'rrrr,zOptional[RevisionMap]rIrJrrrXr)rzUnion[Set[str], List[str]]rIz=Union[Tuple[List[Any], str, str], Tuple[List[str], str, str]])rrrIzTuple[str, str, List[str]]r)rrrIzUnion[Set[str], bool]r)rKrLrMr4rFr@rrdrNrirnrCrDrrrrrrrrrrxrAr5r3rrs;/3 )4 )3 ) )  ) , )  )C     *  / F   # 6  #!    r5r)E __future__r contextlibrrloggingrmtypingrrrr r r r r rrrrr sqlalchemyrrrsqlalchemy.enginerrr}sqlalchemy.engine.strategiesrtyping_extensionsrrrr util.compatrrr sqlalchemy.engine.baser!r"sqlalchemy.engine.mockr#sqlalchemy.sqlr$ environmentr&rr' script.baser(r)script.revisionr*r+r, getLoggerrKrwr.rHrr&rBrKrrAr5r3rs#%"  %$-;,#)%125)/$-1*-g!77:^  ^  Bl-l-^@N@NF0"0"f_ =_ Dv v r5