U ofiq@sUddlmZddlZddlZddlmZddlmZddlmZddlmZddlm Z ddlm Z dd lm Z dd lm Z dd lm Z dd lmZdd lmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZer@ddlmZddlmZddl m!Z!ddl m"Z"dd l#m$Z$dd!l%m&Z&dd"l'm(Z(dd#l'm)Z)dd$l*m+Z+dd%l*m,Z,dd&l-m.Z.dd'l-m/Z/dd(l-m0Z0dd)l-m1Z1dd*l-m2Z2dd+l-m3Z3dd,l4m5Z5dd-l6m7Z7dd.lm8Z8dd/l9m:Z:dd0l;me?Z@Gd2d3d3eAZBiZCd4eDd5<Gd6d7d7eBd8ZEGd9d:d:e ZFd;d;dd?d@ZGdS)A) annotationsN)Any)Callable)Dict)Iterable)List)Mapping) NamedTuple)Optional)Sequence)Set)Tuple)Type) TYPE_CHECKING)Union)castschema)text)_autogen)base)_constraint_sig)ComparisonResult)util) sqla_compat)Literal)TextIO) Connection)Dialect) CursorResult) Inspector) ClauseElement) Executable) ColumnElement) quoted_name)Column) Constraint)ForeignKeyConstraint)Index)Table)UniqueConstraint) TableClause) TypeEngine)_ServerDefault)AutogenContext)ApplyBatchImpl)BatchOperationsImplc@seZdZddddddZdS)ImplMetastrzTuple[Type[DefaultImpl]]Dict[str, Any]) classnamebasesdict_cCs(t||||}d|kr$|t|d<|S)N __dialect__)type__init___impls)clsr6r7r8Znewtyper>>/opt/hc_python/lib/python3.8/site-packages/alembic/ddl/impl.pyr;@s zImplMeta.__init__N)__name__ __module__ __qualname__r;r>r>r>r?r3?sr3zDict[str, Type[DefaultImpl]]r<c@sneZdZUdZdZdZdZddhfZded<d Z d ed <d Z d ed<ddddddddddZ e dddddZ ddddd Zd!dd"d#d$Zd%d&dd'd(d)Zedd*d+d,Zd-d-efd.d/d0d1d2d3d4d5Zdd.d6dd7d8d9Zddddd:d;dddd?dd@dAdBZdddCdDddEdFdGZdddCd;ddEdHdIZd?ddJdKdLZdMddJdNdOZdddPdDddQdRdSZd&ddTdUdVZd&ddTdWdXZdYd?ddZd[d\Zd&ddTd]d^Z d&ddTd_d`Z!daddbdcddZ"dYd?ddZdedfZ#ddhdidddjdkdlZ$dmdndbdodpZ%dndnddqdrdsZ&dndnddtdudvZ'dCdmddwdxdyZ(dzd{Z)d|d}d|d}dd~ddZ*ddZ+dddd?ddddZ,dddddZ-ddddddZ.ddZ/dd*ddZ0dd*ddZ1dd*ddZ2ddddddZ3ddZ4dYdYd;dddZ5dd?ddddZ6dd?ddddZ7dYdYddddZ8ddddddZ9ddZ:ddddddZ;d-S) DefaultImplaProvide the entrypoint for major migration operations, including database-specific behavioral variances. While individual SQL/DDL constructs already provide for database-specific implementations, variances here allow for entirely different sequences of operations to take place for a particular migration, such as SQL Server's special 'IDENTITY INSERT' step for bulk inserts. defaultF;ZNUMERICZDECIMALzTuple[Set[str], ...] type_synonymsr>z Sequence[str]type_arg_extract)orderZon_nullzTuple[str, ...]identity_attrs_ignorer zOptional[Connection]boolzOptional[bool]zOptional[TextIO]r5None)dialect connectionas_sqltransactional_ddl output_buffer context_optsreturncCsZ||_||_||_|dd|_||_i|_||_|dk r@||_|jrV|jsVt ddS)N literal_bindsFz3Can't use literal_binds setting without as_sql mode) rLrMrNgetrSrPmemorQrOr CommandError)selfrLrMrNrOrPrQr>r>r?r;hs zDefaultImpl.__init__zType[DefaultImpl])rLrRcCs t|jSN)r<name)r=rLr>r>r?get_by_dialectszDefaultImpl.get_by_dialectr4)rrRcCs,|jdk st|j|d|jdS)Nz )rPAssertionErrorwriteflush)rWrr>r>r? static_outputszDefaultImpl.static_outputr2)batch_oprRcCsdS)zReturn True if the given :class:`.BatchOperationsImpl` would need the table to be recreated and copied in order to proceed. Normally, only returns True on SQLite when operations other than add_column are present. Fr>)rWr_r>r>r?requires_recreate_in_batchs z&DefaultImpl.requires_recreate_in_batchr1r+) batch_impltablerRcCsdS)zperform any operations needed on a table before a new one is created to replace it in batch mode. the PG dialect uses this to drop constraints on the table before the new one uses those same names. Nr>)rWrarbr>r>r?prep_table_for_batchsz DefaultImpl.prep_table_for_batch)rRcCs|jSrX)rMrWr>r>r?bindszDefaultImpl.bindNzUnion[Executable, str]zOptional[Mapping[str, Any]]z%Optional[Sequence[Mapping[str, Any]]]Mapping[str, Any]zOptional[CursorResult]) constructexecution_options multiparamsparamsrRcCst|trt|}|jr|dk s$|r,td|jrNt|tjsNtddid}ni}t rdt|t sdt |j fd|j i|}|t|dd|jdS|j}|dk st |r|jf|}|r|dk rtd|r|||S|||SdS) Nz&SQL parameters not allowed with as_sqlrST)compile_kwargsrL z z2Can't send params and multiparams at the same time) isinstancer4rrN TypeErrorrSrZ DDLElementdictrr#r[compilerLr^replacestripcommand_terminatorrMrhexecute)rWrgrhrirj compile_kwcompiledconnr>r>r?_execs>      zDefaultImpl._execzOptional[dict[str, Any]])sqlrhrRcCs|||dSrX)rx)rWryrhr>r>r?rtszDefaultImpl.executez%Union[_ServerDefault, Literal[False]]z Optional[str]zOptional[TypeEngine]z$Optional[Union[str, Literal[False]]]zOptional[_ServerDefault]r) table_name column_namenullableserver_defaultrYtype_r autoincrementcommentexisting_comment existing_typeexisting_server_defaultexisting_nullableexisting_autoincrementkwrRc Ks*|dk s|dk rtjddd|dk rF|tj||||| | | | d|dk ri}t|| rftj}n"t|| rtj }||d<ntj }|||||f|| | | | d||dk r|tj ||||| | | | d| dk r|tj ||| || | | | d|dk r&|tj ||||| | | ddS)NzBautoincrement and existing_autoincrement only make sense for MySQL) stacklevel)rrrrrFimpl)rrrr)rwarnrxrZColumnNullablerZ_server_default_is_computedZComputedColumnDefaultZ_server_default_is_identityZIdentityColumnDefaultZ ColumnDefaultZ ColumnTypeZ ColumnCommentZ ColumnName)rWrzr{r|r}rYr~rrrrrrrrrZcls_r>r>r? alter_columns      zDefaultImpl.alter_columnz Column[Any]z!Optional[Union[str, quoted_name]])rzcolumnrrRcCs|tj|||ddSNr)rxrZ AddColumn)rWrzrrr>r>r? add_columnKszDefaultImpl.add_columncKs|tj|||ddSr)rxrZ DropColumn)rWrzrrrr>r>r? drop_columnSszDefaultImpl.drop_column)constrRcCs(|jdks||r$|t|dSrX)Z _create_rulerxrZ AddConstraintrWrr>r>r?add_constraint\szDefaultImpl.add_constraintr(cCs|t|dSrX)rxrZDropConstraintrr>r>r?drop_constraint`szDefaultImpl.drop_constraintzUnion[str, quoted_name])old_table_namenew_table_namerrRcCs|tj|||ddSr)rxrZ RenameTable)rWrrrr>r>r? rename_tablecszDefaultImpl.rename_table)rbrRcCs|jj||jd|d|t||jj||jd|d|jD]}|t|qB|j j oh|j j }|j }|r|r| ||jD]}|j }|r|r||qdSNF)Z checkfirstZ _ddl_runner)dispatchZ before_createrMrxrZ CreateTableZ after_createZindexes CreateIndexrLZsupports_commentsZinline_commentsrcreate_table_commentcolumnscreate_column_comment)rWrbindexZ with_commentrrr>r>r? create_tablems0   zDefaultImpl.create_tablecCs@|jj||jd|d|t||jj||jd|ddSr)rZ before_droprMrxrZ DropTableZ after_droprWrbr>r>r? drop_tableszDefaultImpl.drop_tabler*)rrrRcKs|tj|f|dSrX)rxrrrWrrr>r>r? create_indexszDefaultImpl.create_indexcCs|t|dSrX)rxrZSetTableCommentrr>r>r?rsz DefaultImpl.create_table_commentcCs|t|dSrX)rxrZDropTableCommentrr>r>r?drop_table_commentszDefaultImpl.drop_table_commentzColumnElement[Any])rrRcCs|t|dSrX)rxrZSetColumnComment)rWrr>r>r?rsz!DefaultImpl.create_column_commentcKs|tj|f|dSrX)rxrZ DropIndexrr>r>r? drop_indexszDefaultImpl.drop_indexTzUnion[TableClause, Table]z List[dict])rbrows multiinsertrRcst|tstdn|r.t|dts.td|jrj|D].}|tjffdd| Dq8n@|r|r|jt|dn"|D]}|tjf|qdS)Nz List expectedrzList of dictionaries expectedcs:i|]2\}}|t|tjs2tj||j|jdn|qS))r~)rmrZ_literal_bindparamcr:).0kvrbr>r? s  z+DefaultImpl.bulk_insert..)ri) rmlistrnrorNrxrZ_insert_inlinevaluesitems)rWrbrrrowr>rr? bulk_inserts.    zDefaultImpl.bulk_insertr'Paramsc Cs|jj|j}td|}g}d}|D] }td|rB|}q,||q,t |d|ddgi}|rtd|D]>}d|kr| d\} } | |j | <qx|j | qx|S)Nz[\w\-_]+|\(.+?\)z^\(.*\)$rrz[^(),]+=)rLZ type_compilerprocessr:lowerrefindallmatchappendrsplitrrkwargsargs) rWrZ definitiontokensZ term_tokensZ paren_termtokenrjtermkeyvalr>r>r?_tokenize_column_types    z!DefaultImpl._tokenize_column_type)inspector_paramsmetadata_paramsrRcCs||j|jkrdSdd|jD}d|jg|j}d|jg|j}|D]*}||h|sp|j|jh|rLdSqLdS)NTcSsg|]}dd|DqS)cSsh|] }|qSr>)r)rtr>r>r? sz=DefaultImpl._column_types_match...r>)rbatchr>r>r? sz3DefaultImpl._column_types_match.. F)token0rFjoinrissubset)rWrrZsynonymsZinspector_all_termsZmetadata_all_termsrr>r>r?_column_types_matchs$   zDefaultImpl._column_types_match)inspected_params meta_paramsrRcCst|jt|jkr$|j|jkr$dSt|jt|jkrH|j|jkrHdSd|j}d|j}|jD]>}t||}t||}|rn|rn|d|dkrndSqndS)aWe want to compare column parameters. However, we only want to compare parameters that are set. If they both have `collation`, we want to make sure they are the same. However, if only one specifies it, dont flag it for being less specific FrrT) lenrrrrrGrsearchgroup)rWrrZinspmetaregmimmr>r>r?_column_args_matchs$      zDefaultImpl._column_args_match)inspector_columnmetadata_columnrRcCs8||}||}|||s$dS|||s4dSdS)zReturns True if there ARE differences between the types of the two columns. Takes impl.type_synonyms into account between retrospected and metadata types TF)rrr)rWrrrrr>r>r? compare_type#s    zDefaultImpl.compare_typecCs||kSrXr>)rWrrZrendered_metadata_defaultZrendered_inspector_defaultr>r>r?compare_server_default3sz"DefaultImpl.compare_server_defaultzSet[UniqueConstraint]z Set[Index]) conn_uniques conn_indexesmetadata_unique_constraintsmetadata_indexesrRcCsdSrXr>)rWrrrrr>r>r?correct_for_autogen_constraints<sz+DefaultImpl.correct_for_autogen_constraintscCs$|jj|jk r t|d||d<dS)Nexpr)r:Z_type_affinityr)rWexistingZexisting_transfernew_typer>r>r?cast_for_batch_migrateEs z"DefaultImpl.cast_for_batch_migrater#)ris_server_defaultrrRcKsddd}t|j|j|dS)zdRender a SQL expression that is typically a server default, index expression, etc. TF)rSZ include_table)rLrk)r4rprL)rWrrrrur>r>r?render_ddl_sql_exprKs zDefaultImpl.render_ddl_sql_exprr"r) inspectorrRcCs|jSrX)autogen_column_reflect)rWrr>r>r?_compat_autogen_column_reflectYsz*DefaultImpl._compat_autogen_column_reflectzSet[ForeignKeyConstraint])conn_fks metadata_fksrRcCsdSrXr>)rWrrr>r>r?correct_for_autogen_foreignkeys\sz+DefaultImpl.correct_for_autogen_foreignkeyscCsdS)zA hook that is attached to the 'column_reflect' event for when a Table is reflected from the database during the autogenerate process. Dialects can elect to modify the information gathered here. Nr>)rWrrbZ column_infor>r>r?rcsz"DefaultImpl.autogen_column_reflectcCsdS)zA hook called when :meth:`.EnvironmentContext.run_migrations` is called. Implementations can set up per-migration-run state here. Nr>rdr>r>r?start_migrationslszDefaultImpl.start_migrationscCs|d|jdS)zEmit the string ``BEGIN``, or the backend-specific equivalent, on the current connection context. This is used in offline mode and typically via :meth:`.EnvironmentContext.begin_transaction`. ZBEGINNr^rsrdr>r>r? emit_begintszDefaultImpl.emit_begincCs|d|jdS)zEmit the string ``COMMIT``, or the backend-specific equivalent, on the current connection context. This is used in offline mode and typically via :meth:`.EnvironmentContext.begin_transaction`. ZCOMMITNrrdr>r>r? emit_commit~szDefaultImpl.emit_commitr.r0zUnion[str, Literal[False]])type_objautogen_contextrRcCsdSNFr>)rWrrr>r>r? render_typeszDefaultImpl.render_typecCsvt||tdhd\}}t|dd}t|dd}t|t|krL|d||j||t|prt|t|kfS)Nalways)skip)_compare_identity_optionsrZIdentitygetattrrJadddifference_updaterI)rWZmetadata_identityZinspector_identitydiffZignoredZ meta_alwaysZinspector_alwaysr>r>r?_compare_identity_defaults     z%DefaultImpl._compare_identity_default)metadata_indexreflected_indexrRcCs4t|j}t|j}||kr,d|d|SdSdS)Nzunique=z to unique=)rJunique)rWrrZ conn_uniqueZ meta_uniquer>r>r?_compare_index_uniques   z!DefaultImpl._compare_index_uniquez _autogen._Cz_constraint_sig[_autogen._C]) constraintoptsrRcKstjd||f|S)NTrZfrom_constraintrWrrr>r>r?_create_metadata_constraint_sigsz+DefaultImpl._create_metadata_constraint_sigcKstjd||f|Srrrr>r>r? _create_reflected_constraint_sigsz,DefaultImpl._create_reflected_constraint_sigrcCsg}|||}|r||||}||}t|s@tt|sNt||fD]}|jrVt d|j qV|j |j kr|d|j d|j |rt |St SdS)zCompare two indexes by comparing the signature generated by ``create_index_sig``. This method returns a ``ComparisonResult``. zGenerating approximate signature for index %s. The dialect implementation should either skip expression indexes or provide a custom implementation. expression  to N)rrrrrZ is_index_sigr[Zhas_expressionslogwarningrZ column_namesr DifferentEqual)rWrrmsgZ unique_msgZm_sigZr_sigsigr>r>r?compare_indexess0       zDefaultImpl.compare_indexesr,)metadata_constraintreflected_constraintrRcCsJ||}||}|j}|j}||kr>td|d|StSdS)aCompare two unique constraints by comparing the two signatures. The arguments are two tuples that contain the unique constraint and the signatures generated by ``create_unique_constraint_sig``. This method returns a ``ComparisonResult``. rrN)rrunnamedrr r )rWrrZ metadata_tupZ reflected_tupZmeta_sigZconn_sigr>r>r?compare_unique_constraints z%DefaultImpl.compare_unique_constraintc Cshdd|D}t|D]L}|j|kr&qt|}|rtd|jd|jdtjd||qdS)NcSsi|] }|j|qSr>)rY)rrr>r>r?rsz8DefaultImpl._skip_functional_indexes..z@autogenerate skipping metadata-specified expression-based index z ; dialect z under SQLAlchemy z6 can't reflect these indexes so they can't be compared) rrYrZis_expression_indexrrr9Zsqlalchemy_versiondiscard)rWrrZconn_indexes_by_nameidxiexr>r>r?_skip_functional_indexess   z$DefaultImpl._skip_functional_indexes)reflected_objectkindrRcCs |diS)NZdialect_options)rT)rWrrr>r>r? adjust_reflected_dialect_optionssz,DefaultImpl.adjust_reflected_dialect_options)N) NFNNNNFNNNNN)N)N)N)T)F)r>r>r?rCOs      0 .t    ((!      +rC) metaclassc@s.eZdZUded<ded<ded<ded<dS) rr4rz List[str]rrzDict[str, str]rN)r@rArBrr>r>r>r?rs rz-Union[schema.Identity, schema.Sequence, None]z'Union[schema.Identity, schema.Sequence]zSet[str]) metadata_io inspector_io default_iorcst|}t|}ttdddddfdd }|||t|t||tjr|t|dit|di|jt|difS)Nrfz Iterable[str]) meta_dict insp_dict default_dictattrscs\t|D]H}||}||}||kr||}||krL|q|qdSrX)set differencerTr)r#r$r%r&attrZ meta_valueZ insp_value default_valuerZ ignored_attrrr>r? check_dicts1s    z._compare_identity_options..check_dictsdialect_kwargs)rZ_get_identity_options_dictr'unionZidentity_has_dialect_kwargsrr-)r r!r"rZmeta_dZinsp_dr,r>r+r?r"s&      r)H __future__rloggingrtypingrrrrrrr r r r r rrrZ sqlalchemyrrrrrrrrrrrZsqlalchemy.enginerr Zsqlalchemy.engine.cursorr!Zsqlalchemy.engine.reflectionr"Zsqlalchemy.sqlr#r$Zsqlalchemy.sql.elementsr%r&Zsqlalchemy.sql.schemar'r(r)r*r+r,Zsqlalchemy.sql.selectabler-Zsqlalchemy.sql.type_apir.r/Zautogenerate.apir0Zoperations.batchr1r2 getLoggerr@r r:r3r<rrCrrr>r>r>r?sx                                                Q