ÿØÿàJFIFÿþ ÿÛC       ÿÛC ÿÀÿÄÿÄ"#QrÿÄÿÄ&1!A"2qQaáÿÚ ?Øy,æ/3JæÝ¹È߲؋5êXw²±ÉyˆR”¾I0ó2—PI¾IÌÚiMö¯–þrìN&"KgX:Šíµ•nTJnLK„…@!‰-ý ùúmë;ºgµŒ&ó±hw’¯Õ@”Ü— 9ñ-ë.²1<yà‚¹ïQÐU„ہ?.’¦èûbß±©Ö«Âw*VŒ) `$‰bØÔŸ’ëXÖ-ËTÜíGÚ3ð«g Ÿ§¯—Jx„–’U/ÂÅv_s(Hÿ@TñJÑãõçn­‚!ÈgfbÓc­:él[ðQe 9ÀPLbÃãCµm[5¿ç'ªjglå‡Ûí_§Úõl-;"PkÞÞÁQâ¼_Ñ^¢SŸx?"¸¦ùY騐ÒOÈ q’`~~ÚtËU¹CڒêV  I1Áß_ÿÙ M!Vc@sdZddlmZddlmZddlmZddlmZddlmZdd l Z d Z d Z d d e dd dZdZdefdYZdefdYZd S(sXProvide the 'autogenerate' feature which can produce migration operations automatically.i(topsi(trender(tcompare(tutili(t InspectorNcCst||}|jjS(s Compare a database schema to that given in a :class:`~sqlalchemy.schema.MetaData` instance. The database connection is presented in the context of a :class:`.MigrationContext` object, which provides database connectivity as well as optional comparison functions to use for datatypes and server defaults - see the "autogenerate" arguments at :meth:`.EnvironmentContext.configure` for details on these. The return format is a list of "diff" directives, each representing individual differences:: from alembic.migration import MigrationContext from alembic.autogenerate import compare_metadata from sqlalchemy.schema import SchemaItem from sqlalchemy.types import TypeEngine from sqlalchemy import (create_engine, MetaData, Column, Integer, String, Table) import pprint engine = create_engine("sqlite://") engine.execute(''' create table foo ( id integer not null primary key, old_data varchar, x integer )''') engine.execute(''' create table bar ( data varchar )''') metadata = MetaData() Table('foo', metadata, Column('id', Integer, primary_key=True), Column('data', Integer), Column('x', Integer, nullable=False) ) Table('bat', metadata, Column('info', String) ) mc = MigrationContext.configure(engine.connect()) diff = compare_metadata(mc, metadata) pprint.pprint(diff, indent=2, width=20) Output:: [ ( 'add_table', Table('bat', MetaData(bind=None), Column('info', String(), table=), schema=None)), ( 'remove_table', Table(u'bar', MetaData(bind=None), Column(u'data', VARCHAR(), table=), schema=None)), ( 'add_column', None, 'foo', Column('data', Integer(), table=)), ( 'remove_column', None, 'foo', Column(u'old_data', VARCHAR(), table=None)), [ ( 'modify_nullable', None, 'foo', u'x', { 'existing_server_default': None, 'existing_type': INTEGER()}, True, False)]] :param context: a :class:`.MigrationContext` instance. :param metadata: a :class:`~sqlalchemy.schema.MetaData` instance. .. seealso:: :func:`.produce_migrations` - produces a :class:`.MigrationScript` structure based on metadata comparison. (tproduce_migrationst upgrade_opstas_diffs(tcontexttmetadatatmigration_script((sI/opt/alt/python27/lib/python2.7/site-packages/alembic/autogenerate/api.pytcompare_metadata sZcCsVt|d|}tjdddtjgdtjg}tj|||S(sProduce a :class:`.MigrationScript` structure based on schema comparison. This function does essentially what :func:`.compare_metadata` does, but then runs the resulting list of diffs to produce the full :class:`.MigrationScript` object. For an example of what this looks like, see the example in :ref:`customizing_revision`. .. versionadded:: 0.8.0 .. seealso:: :func:`.compare_metadata` - returns more fundamental "diff" data from comparing a schema. R trev_idRt downgrade_opsN(tAutogenContextRtMigrationScripttNonet UpgradeOpst DowngradeOpsRt_populate_migration_script(RR tautogen_contextR ((sI/opt/alt/python27/lib/python2.7/site-packages/alembic/autogenerate/api.pyRjs ssa.sop.cCs\i|d6|d6|d6|d6}tdd|}t||_tjtj||S(sRender Python code given an :class:`.UpgradeOps` or :class:`.DowngradeOps` object. This is a convenience function that can be used to test the autogenerate output of a user-defined :class:`.MigrationScript` structure. tsqlalchemy_module_prefixtalembic_module_prefixt render_itemtrender_as_batchtoptsN(RRtsettimportsRt_indentt_render_cmd_body(t up_or_down_opRRRRRRR((sI/opt/alt/python27/lib/python2.7/site-packages/alembic/autogenerate/api.pytrender_python_codes  cCsft|}tjg}tj||tjddd|d|j}tj |||dS(s6legacy, used by test_autogen_composition at the momentR RR N( RRRRt_produce_net_changesRRtreverseRt _render_python_into_templatevars(Rt template_argsRRR ((sI/opt/alt/python27/lib/python2.7/site-packages/alembic/autogenerate/api.pyt_render_migration_diffss  RcBskeZdZdZdZdZdZdZdde dZ e j dZ ejdZdZRS(sSMaintains configuration and state that's specific to an autogenerate operation.cs||r-|dk r-|jr-tjdn|dkrE|j}n|dkrc|jddn||_}|dkr|dk r|jdk rtjd|jjn|jdd|jdd}g}rfd}|j |n|r|j |n||_ ||_ |j dk rZ|j j |_ |j j|_nt|_||_t|_dS(Ns^autogenerate can't use as_sql=True as it prevents querying the database for schema informationttarget_metadatasrCan't proceed with --autogenerate option; environment script %s does not provide a MetaData object to the context.tinclude_symboltinclude_objectcs$|dkr||jStSdS(Nttable(tschematTrue(tobjecttnamettype_t reflectedt compare_to(R&(sI/opt/alt/python27/lib/python2.7/site-packages/alembic/autogenerate/api.pytinclude_symbol_filters (Rtas_sqlRt CommandErrorRtgetR tscripttenv_py_locationtappendt_object_filterstmigration_contexttbindt connectiontdialectRRtFalset _has_batch(tselfR8R Rt autogenerateR'tobject_filtersR0((R&sI/opt/alt/python27/lib/python2.7/site-packages/alembic/autogenerate/api.pyt__init__s:   +      cCstj|jS(N(Rt from_engineR:(R>((sI/opt/alt/python27/lib/python2.7/site-packages/alembic/autogenerate/api.pyt inspector&sccst|_dVt|_dS(N(R*R=R<(R>((sI/opt/alt/python27/lib/python2.7/site-packages/alembic/autogenerate/api.pyt _within_batch*s cCs8x1|jD]"}||||||s tSq WtSdS(s4Run the context's object filters and return True if the targets should be part of the autogenerate operation. This method should be run for every kind of object encountered within an autogenerate operation, giving the environment the chance to filter what objects should be included in the comparison. The filters here are produced directly via the :paramref:`.EnvironmentContext.configure.include_object` and :paramref:`.EnvironmentContext.configure.include_symbol` functions, if present. N(R7R<R*(R>tobject_R,R-R.R/tfn((sI/opt/alt/python27/lib/python2.7/site-packages/alembic/autogenerate/api.pyt run_filters0s N(t__name__t __module__t__doc__RR R:R;RR8R*RARtmemoized_propertyRCt contextlibtcontextmanagerRDRG(((sI/opt/alt/python27/lib/python2.7/site-packages/alembic/autogenerate/api.pyRs 2tRevisionContextcBsMeZdZdZdZdZdZdZdZdZ RS(s^Maintains configuration and state that's specific to a revision file generation operation.cCsA||_||_||_i|d6|_|jg|_dS(Ntconfig(ROtscript_directoryt command_argsR#t_default_revisiontgenerated_revisions(R>RORPRQ((sI/opt/alt/python27/lib/python2.7/site-packages/alembic/autogenerate/api.pyRAHs     cCsi}x-|jjD]\}}|j||qWt|dtr|j}t|_|jr||jj|jnt j |||n|j j |j |jdtd|jd|jd|jd|jd|j|S(Nt _needs_rendertrefreshtheadtsplicet branch_labelst version_patht depends_on(R#titemst setdefaulttgetattrR<t_last_autogen_contextRRt union_updateRR"RPtgenerate_revisionR tmessageR*RVRWt branch_labelRYRZ(R>R R#tktvR((sI/opt/alt/python27/lib/python2.7/site-packages/alembic/autogenerate/api.pyt _to_scriptTs(         cCs|j||tdS(N(t_run_environmentR*(R>trevR8((sI/opt/alt/python27/lib/python2.7/site-packages/alembic/autogenerate/api.pytrun_autogeneratepscCs|j||tdS(N(RfR<(R>RgR8((sI/opt/alt/python27/lib/python2.7/site-packages/alembic/autogenerate/api.pytrun_no_autogeneratessc Cs|rj|jdr%tjdnt|jj|t|jjdkrjtjdqjn|jd}|jd}|jd}t|dt s||j d_ ||j d_ t|_n>|jjtjgd||jjtjgd|t|d ||_}|r?tj||n|jd }|rh||||jnx|jD]}t|_qrWdS( Ntsqls7Using --sql with --autogenerate does not make any sensetheadss"Target database is not up to date.t upgrade_tokentdowngrade_tokeniRTR?tprocess_revision_directives(RQRR2RRPt get_revisionsRRSR]R<tupgrade_ops_listRltdowngrade_ops_listRmR*RTt _upgrade_opsR6RRt_downgrade_opsRRR^RR( R>RgR8R?RlRmR Rthook((sI/opt/alt/python27/lib/python2.7/site-packages/alembic/autogenerate/api.pyRfvs6          cCstjd|jdptjd|jddtjgdtjgd|jdd|jdd|jdd|jdd |jd  }|S( NR RaRR RVRWRbRYRZ(RRRQRR RR(R>top((sI/opt/alt/python27/lib/python2.7/site-packages/alembic/autogenerate/api.pyRRs      ccs&x|jD]}|j|Vq WdS(N(RSRe(R>tgenerated_revision((sI/opt/alt/python27/lib/python2.7/site-packages/alembic/autogenerate/api.pytgenerate_scriptss( RHRIRJRAReRhRiRfRRRw(((sI/opt/alt/python27/lib/python2.7/site-packages/alembic/autogenerate/api.pyRNDs    ( ((RJt operationsRtRRRtsqlalchemy.engine.reflectionRRLR RR<RRR$R+RRN(((sI/opt/alt/python27/lib/python2.7/site-packages/alembic/autogenerate/api.pyts   ^ !