U
    [h                     @   s   d Z ddlZddlmZ ddlmZ ddlmZ ddlmZ dd	lmZ dd
lm	Z	 ddlm
Z
 ddl	mZ ddl	mZ ddlmZ ddl
mZ e
jdd ZejG dd deZdS )a  Provides an abstraction for obtaining database schema information.

Usage Notes:

Here are some general conventions when accessing the low level inspector
methods such as get_table_names, get_columns, etc.

1. Inspector methods return lists of dicts in most cases for the following
   reasons:

   * They're both standard types that can be serialized.
   * Using a dict instead of a tuple allows easy expansion of attributes.
   * Using a list for the outer structure maintains order and is easy to work
     with (e.g. list comprehension [d['name'] for d in cols]).

2. Records that contain a name, such as the column name in a column record
   use the key 'name'. So for most return values, each record will have a
   'name' attribute..
    N   )Connectable)
Connection)Engine   )exc)
inspection)sql)util)	operators)schema)
TypeEngine)topologicalc                 O   s   | dd }|d kr&| ||f||S | jtdd |D tdd | D f}| |}|d kr~| ||f||}|||< |S )N
info_cachec                 s   s   | ]}t |tjr|V  qd S N)
isinstancer
   string_types).0a r   @/tmp/pip-unpacked-wheel-joqu7d3y/sqlalchemy/engine/reflection.py	<genexpr>2   s      zcache.<locals>.<genexpr>c                 s   s"   | ]\}}|d kr||fV  qdS )r   Nr   )r   kvr   r   r   r   3   s      )get__name__tupleitems)fnselfconargskwr   keyretr   r   r   cache+   s    
r%   c                   @   s  e Zd ZdZedddd Zedd Zdd	 Z	d
d Z
dd Zeedddd Zeedd Zeedd Zeedd Zejdd Zejdd Zedd Zdd Zd^d d!Zd_d"d#Zd`d$d%Zdad&d'Zd(d) Z d*d+ Z!dbd,d-Z"dcd.d/Z#ddd0d1Z$ded2d3Z%dfd4d5Z&dgd6d7Z'dhd8d9Z(did:d;Z)djd<d=Z*dkd>d?Z+dld@dAZ,e-dBdCdDdE Z.dmdHdIZ/dJdK Z0dLdM Z1dNdO Z2dPdQ Z3dRe4j5fdSe4j6fdTe4j7fdUe4j8fgZ9dVdW Z:dXdY Z;dZd[ Z<d\d] Z=dS )n	Inspectora<  Performs database schema inspection.

    The Inspector acts as a proxy to the reflection methods of the
    :class:`~sqlalchemy.engine.interfaces.Dialect`, providing a
    consistent interface as well as caching support for previously
    fetched metadata.

    A :class:`_reflection.Inspector` object is usually created via the
    :func:`_sa.inspect` function, which may be passed an
    :class:`_engine.Engine`
    or a :class:`_engine.Connection`::

        from sqlalchemy import inspect, create_engine
        engine = create_engine('...')
        insp = inspect(engine)

    Where above, the :class:`~sqlalchemy.engine.interfaces.Dialect` associated
    with the engine may opt to return an :class:`_reflection.Inspector`
    subclass that
    provides additional methods specific to the dialect's target database.

    z1.4a  The __init__() method on :class:`_reflection.Inspector` is deprecated and will be removed in a future release.  Please use the :func:`.sqlalchemy.inspect` function on an :class:`_engine.Engine` or :class:`_engine.Connection` in order to acquire an :class:`_reflection.Inspector`.c                 C   s
   |  |S )a  Initialize a new :class:`_reflection.Inspector`.

        :param bind: a :class:`~sqlalchemy.engine.Connectable`,
          which is typically an instance of
          :class:`~sqlalchemy.engine.Engine` or
          :class:`~sqlalchemy.engine.Connection`.

        For a dialect-specific instance of :class:`_reflection.Inspector`, see
        :meth:`_reflection.Inspector.from_engine`

        )_init_legacyr   bindr   r   r   __init__U   s    zInspector.__init__c                 C   s,   t |jdr|jj} | | }||| |S )N	inspector)hasattrdialectr+   __new__)clsinitr)   r   r   r   r   
_constructn   s
    

zInspector._constructc                 C   s$   t |dr| | n
| | d S )NZexec_driver_sql)r,   _init_connection_init_enginer(   r   r   r   r'   x   s    
zInspector._init_legacyc                 C   s2   | | _ | _|   d| _| jj| _i | _d S )NT)r)   engineconnectclose_op_context_requires_connectr-   r   )r   r4   r   r   r   r3   ~   s
    
zInspector._init_enginec                 C   s(   || _ |j| _d| _| jj| _i | _d S )NF)r)   r4   r7   r-   r   )r   
connectionr   r   r   r2      s
    
zInspector._init_connectiona  The from_engine() method on :class:`_reflection.Inspector` is deprecated and will be removed in a future release.  Please use the :func:`.sqlalchemy.inspect` function on an :class:`_engine.Engine` or :class:`_engine.Connection` in order to acquire an :class:`_reflection.Inspector`.c                 C   s   |  | j|S )a  Construct a new dialect-specific Inspector object from the given
        engine or connection.

        :param bind: a :class:`~sqlalchemy.engine.Connectable`,
          which is typically an instance of
          :class:`~sqlalchemy.engine.Engine` or
          :class:`~sqlalchemy.engine.Connection`.

        This method differs from direct a direct constructor call of
        :class:`_reflection.Inspector` in that the
        :class:`~sqlalchemy.engine.interfaces.Dialect` is given a chance to
        provide a dialect-specific :class:`_reflection.Inspector` instance,
        which may
        provide additional methods.

        See the example at :class:`_reflection.Inspector`.

        )r1   r'   )r/   r)   r   r   r   from_engine   s    zInspector.from_enginec                 C   s   t t j| S r   )r&   r1   r'   r)   r   r   r   _connectable_insp   s    zInspector._connectable_inspc                 C   s   t t j| S r   )r&   r1   r3   r:   r   r   r   _engine_insp   s    zInspector._engine_inspc                 C   s   t t j| S r   )r&   r1   r2   r:   r   r   r   _connection_insp   s    zInspector._connection_inspc                 c   s8   | j r| j }n| j}z
|V  W 5 | j r2|  X dS )a  Return a context that optimizes for multiple operations on a single
        transaction.

        This essentially allows connect()/close() to be called if we detected
        that we're against an :class:`_engine.Engine` and not a
        :class:`_engine.Connection`.

        N)r7   r)   r5   r6   r   connr   r   r   _operation_context   s    

zInspector._operation_contextc              	   c   s6   |   $}| | jj|}| j|_|V  W 5 Q R X dS )zReturn an :class:`_reflection.Inspector`
        from this one that will run all
        operations on a single connection.

        N)r@   r1   	__class__r2   r   )r   r?   Zsub_inspr   r   r   _inspection_context   s    
zInspector._inspection_contextc                 C   s   | j jS )zReturn the default schema name presented by the dialect
        for the current engine's database user.

        E.g. this is typically ``public`` for PostgreSQL and ``dbo``
        for SQL Server.

        )r-   default_schema_name)r   r   r   r   rC      s    	zInspector.default_schema_namec              
   C   s>   t | jdr:|   }| jj|| jdW  5 Q R  S Q R X g S )zReturn all schema names.get_schema_namesr   )r,   r-   r@   rD   r   r>   r   r   r   rD      s    
 zInspector.get_schema_namesNc              
   C   s4   |   "}| jj||| jdW  5 Q R  S Q R X dS )a  Return all table names in referred to within a particular schema.

        The names are expected to be real tables only, not views.
        Views are instead returned using the
        :meth:`_reflection.Inspector.get_view_names`
        method.


        :param schema: Schema name. If ``schema`` is left at ``None``, the
         database's default schema is
         used, else the named schema is searched.  If the database does not
         support named schemas, behavior is undefined if ``schema`` is not
         passed as ``None``.  For special quoting, use :class:`.quoted_name`.

        .. seealso::

            :meth:`_reflection.Inspector.get_sorted_table_and_fkc_names`

            :attr:`_schema.MetaData.sorted_tables`

        rE   N)r@   r-   get_table_namesr   r   r   r?   r   r   r   rF      s    
  zInspector.get_table_namesc              
   C   s0   |   }| j|||W  5 Q R  S Q R X dS )aM  Return True if the backend has a table of the given name.


        :param table_name: name of the table to check
        :param schema: schema name to query, if not the default schema.

        .. versionadded:: 1.4 - the :meth:`.Inspector.has_table` method
           replaces the :meth:`_engine.Engine.has_table` method.

        N)r@   r-   	has_table)r   
table_namer   r?   r   r   r   rH     s    
zInspector.has_tablec              
   C   s0   |   }| j|||W  5 Q R  S Q R X dS )zReturn True if the backend has a table of the given name.

        :param sequence_name: name of the table to check
        :param schema: schema name to query, if not the default schema.

        .. versionadded:: 1.4

        N)r@   r-   has_sequence)r   Zsequence_namer   r?   r   r   r   rJ     s    

zInspector.has_sequencec           
   
      s0  |   }| jj||| jd}W 5 Q R X t }t i |D ]N}| ||}tdd |D |< |D ]"}||d krf||d |f qfq<ztt	||}W nl t
jk
r }	 zJ|	jD ]. |   fdd d  D  qtt	||}W 5 d}	~	X Y nX fd	d|D dtfg S )
a  Return dependency-sorted table and foreign key constraint names in
        referred to within a particular schema.

        This will yield 2-tuples of
        ``(tablename, [(tname, fkname), (tname, fkname), ...])``
        consisting of table names in CREATE order grouped with the foreign key
        constraint names that are not detected as belonging to a cycle.
        The final element
        will be ``(None, [(tname, fkname), (tname, fkname), ..])``
        which will consist of remaining
        foreign key constraint names that would require a separate CREATE
        step after-the-fact, based on dependencies between tables.

        .. versionadded:: 1.0.-

        .. seealso::

            :meth:`_reflection.Inspector.get_table_names`

            :func:`.sort_tables_and_constraints` - similar method which works
            with an already-given :class:`_schema.MetaData`.

        rE   c                 S   s   g | ]}|d  qS )namer   )r   Zfkr   r   r   
<listcomp>N  s     z<Inspector.get_sorted_table_and_fkc_names.<locals>.<listcomp>referred_tablec                 3   s   | ]} d  |fV  qdS )r   Nr   )r   Zfkc)edger   r   r   W  s    z;Inspector.get_sorted_table_and_fkc_names.<locals>.<genexpr>r   Nc                    s   g | ]}| |  fqS r   )
difference)r   tname)fknames_for_tableremaining_fkcsr   r   rL   \  s   )r@   r-   rF   r   setget_foreign_keysaddlistr   sortr   ZCircularDependencyErroredgesremoveupdate)
r   r   r?   ZtnamesZtuplesrP   fkeysZfkeyZcandidate_sorterrr   )rN   rQ   rR   r   get_sorted_table_and_fkc_names*  s:    
  



"z(Inspector.get_sorted_table_and_fkc_namesc              
   C   s2   |    }| jj|| jdW  5 Q R  S Q R X dS )zReturn a list of temporary table names for the current bind.

        This method is unsupported by most dialects; currently
        only SQLite implements it.

        .. versionadded:: 1.0.0

        rE   N)r@   r-   get_temp_table_namesr   r>   r   r   r   r^   a  s
    

 zInspector.get_temp_table_namesc              
   C   s2   |    }| jj|| jdW  5 Q R  S Q R X dS )zReturn a list of temporary view names for the current bind.

        This method is unsupported by most dialects; currently
        only SQLite implements it.

        .. versionadded:: 1.0.0

        rE   N)r@   r-   get_temp_view_namesr   r>   r   r   r   r_   p  s
    	
 zInspector.get_temp_view_namesc              
   K   sJ   t | jdrF|  ,}| jj|||fd| ji|W  5 Q R  S Q R X i S )a  Return a dictionary of options specified when the table of the
        given name was created.

        This currently includes some options that apply to MySQL tables.

        :param table_name: string name of the table.  For special quoting,
         use :class:`.quoted_name`.

        :param schema: string schema name; if omitted, uses the default schema
         of the database connection.  For special quoting,
         use :class:`.quoted_name`.

        get_table_optionsr   )r,   r-   r@   r`   r   r   rI   r   r"   r?   r   r   r   r`   ~  s    
  zInspector.get_table_optionsc              
   C   s4   |   "}| jj||| jdW  5 Q R  S Q R X dS )zReturn all view names in `schema`.

        :param schema: Optional, retrieve names from a non-default schema.
         For special quoting, use :class:`.quoted_name`.

        rE   N)r@   r-   get_view_namesr   rG   r   r   r   rb     s    
  zInspector.get_view_namesc              
   C   s4   |   "}| jj||| jdW  5 Q R  S Q R X dS )zReturn all sequence names in `schema`.

        :param schema: Optional, retrieve names from a non-default schema.
         For special quoting, use :class:`.quoted_name`.

        rE   N)r@   r-   get_sequence_namesr   rG   r   r   r   rc     s    
  zInspector.get_sequence_namesc              
   C   s6   |   $}| jj|||| jdW  5 Q R  S Q R X dS )zReturn definition for `view_name`.

        :param schema: Optional, retrieve names from a non-default schema.
         For special quoting, use :class:`.quoted_name`.

        rE   N)r@   r-   get_view_definitionr   )r   Z	view_namer   r?   r   r   r   rd     s    
   zInspector.get_view_definitionc              	   K   s\   |   $}| jj|||fd| ji|}W 5 Q R X |D ] }|d }t|ts6| |d< q6|S )a  Return information about columns in `table_name`.

        Given a string `table_name` and an optional string `schema`, return
        column information as a list of dicts with these keys:

        * ``name`` - the column's name

        * ``type`` - the type of this column; an instance of
          :class:`~sqlalchemy.types.TypeEngine`

        * ``nullable`` - boolean flag if the column is NULL or NOT NULL

        * ``default`` - the column's server default value - this is returned
          as a string SQL expression.

        * ``autoincrement`` - indicates that the column is auto incremented -
          this is returned as a boolean or 'auto'

        * ``comment`` - (optional) the comment on the column. Only some
          dialects return this key

        * ``computed`` - (optional) when present it indicates that this column
          is computed by the database. Only some dialects return this key.
          Returned as a dict with the keys:

          * ``sqltext`` - the expression used to generate this column returned
            as a string SQL expression

          * ``persisted`` - (optional) boolean that indicates if the column is
            stored in the table

          .. versionadded:: 1.3.16 - added support for computed reflection.

        * ``identity`` - (optional) when present it indicates that this column
          is a generated always column. Only some dialects return this key.
          For a list of keywords on this dict see :class:`_schema.Identity`.

          .. versionadded:: 1.4 - added support for identity column reflection.

        * ``dialect_options`` - (optional) a dict with dialect specific options

        :param table_name: string name of the table.  For special quoting,
         use :class:`.quoted_name`.

        :param schema: string schema name; if omitted, uses the default schema
         of the database connection.  For special quoting,
         use :class:`.quoted_name`.

        :return: list of dictionaries, each representing the definition of
         a database column.

        r   type)r@   r-   get_columnsr   r   r   )r   rI   r   r"   r?   Zcol_defsZcol_defcoltyper   r   r   rf     s    6
  
zInspector.get_columnsc              
   K   s>   |   ,}| jj|||fd| ji|W  5 Q R  S Q R X dS )a  Return information about primary key constraint on `table_name`.

        Given a string `table_name`, and an optional string `schema`, return
        primary key information as a dictionary with these keys:

        * ``constrained_columns`` -
          a list of column names that make up the primary key

        * ``name`` -
          optional name of the primary key constraint.

        :param table_name: string name of the table.  For special quoting,
         use :class:`.quoted_name`.

        :param schema: string schema name; if omitted, uses the default schema
         of the database connection.  For special quoting,
         use :class:`.quoted_name`.

        r   N)r@   r-   get_pk_constraintr   ra   r   r   r   rh     s    
  zInspector.get_pk_constraintc              
   K   s>   |   ,}| jj|||fd| ji|W  5 Q R  S Q R X dS )a  Return information about foreign_keys in `table_name`.

        Given a string `table_name`, and an optional string `schema`, return
        foreign key information as a list of dicts with these keys:

        * ``constrained_columns`` -
          a list of column names that make up the foreign key

        * ``referred_schema`` -
          the name of the referred schema

        * ``referred_table`` -
          the name of the referred table

        * ``referred_columns`` -
          a list of column names in the referred table that correspond to
          constrained_columns

        * ``name`` -
          optional name of the foreign key constraint.

        :param table_name: string name of the table.  For special quoting,
         use :class:`.quoted_name`.

        :param schema: string schema name; if omitted, uses the default schema
         of the database connection.  For special quoting,
         use :class:`.quoted_name`.

        r   N)r@   r-   rT   r   ra   r   r   r   rT     s    
  zInspector.get_foreign_keysc              
   K   s>   |   ,}| jj|||fd| ji|W  5 Q R  S Q R X dS )a  Return information about indexes in `table_name`.

        Given a string `table_name` and an optional string `schema`, return
        index information as a list of dicts with these keys:

        * ``name`` -
          the index's name

        * ``column_names`` -
          list of column names in order

        * ``unique`` -
          boolean

        * ``column_sorting`` -
          optional dict mapping column names to tuple of sort keywords,
          which may include ``asc``, ``desc``, ``nulls_first``, ``nulls_last``.

          .. versionadded:: 1.3.5

        * ``dialect_options`` -
          dict of dialect-specific index options.  May not be present
          for all dialects.

          .. versionadded:: 1.0.0

        :param table_name: string name of the table.  For special quoting,
         use :class:`.quoted_name`.

        :param schema: string schema name; if omitted, uses the default schema
         of the database connection.  For special quoting,
         use :class:`.quoted_name`.

        r   N)r@   r-   get_indexesr   ra   r   r   r   ri   8  s    $
  zInspector.get_indexesc              
   K   s>   |   ,}| jj|||fd| ji|W  5 Q R  S Q R X dS )a  Return information about unique constraints in `table_name`.

        Given a string `table_name` and an optional string `schema`, return
        unique constraint information as a list of dicts with these keys:

        * ``name`` -
          the unique constraint's name

        * ``column_names`` -
          list of column names in order

        :param table_name: string name of the table.  For special quoting,
         use :class:`.quoted_name`.

        :param schema: string schema name; if omitted, uses the default schema
         of the database connection.  For special quoting,
         use :class:`.quoted_name`.

        r   N)r@   r-   get_unique_constraintsr   ra   r   r   r   rj   a  s    
  z Inspector.get_unique_constraintsc              
   K   s>   |   ,}| jj|||fd| ji|W  5 Q R  S Q R X dS )a  Return information about the table comment for ``table_name``.

        Given a string ``table_name`` and an optional string ``schema``,
        return table comment information as a dictionary with these keys:

        * ``text`` -
            text of the comment.

        Raises ``NotImplementedError`` for a dialect that does not support
        comments.

        .. versionadded:: 1.2

        r   N)r@   r-   get_table_commentr   ra   r   r   r   rk   {  s    
  zInspector.get_table_commentc              
   K   s>   |   ,}| jj|||fd| ji|W  5 Q R  S Q R X dS )ac  Return information about check constraints in `table_name`.

        Given a string `table_name` and an optional string `schema`, return
        check constraint information as a list of dicts with these keys:

        * ``name`` -
          the check constraint's name

        * ``sqltext`` -
          the check constraint's SQL expression

        * ``dialect_options`` -
          may or may not be present; a dictionary with additional
          dialect-specific options for this CHECK constraint

          .. versionadded:: 1.3.8

        :param table_name: string name of the table.  For special quoting,
         use :class:`.quoted_name`.

        :param schema: string schema name; if omitted, uses the default schema
         of the database connection.  For special quoting,
         use :class:`.quoted_name`.

        .. versionadded:: 1.1.0

        r   N)r@   r-   get_check_constraintsr   ra   r   r   r   rl     s    
  zInspector.get_check_constraintsz*:meth:`_reflection.Inspector.reflecttable`zThe :meth:`_reflection.Inspector.reflecttable` method was renamed to :meth:`_reflection.Inspector.reflect_table`. This deprecated alias will be removed in a future release.c                 O   s   | j ||S )z1See reflect_table. This method name is deprecated)reflect_table)r   r!   kwargsr   r   r   reflecttable  s    	zInspector.reflecttabler   Tc                    s  |dk	r |krdS |   | jj}|  }| }W 5 Q R X  j}	t fdd|jD }
| j|	|f j	}|r 
| tjrt|tr||j}t|	tr|	|j}	d}i }| j|	|f j	D ]}d}|  |||| q|s| |	|st|	| |	| || | |	| ||||||
	 | |	| ||||
 | |	| ||||
 | |	| ||||
 | |	| |
 dS )aZ  Given a :class:`_schema.Table` object, load its internal
        constructs based on introspection.

        This is the underlying method used by most dialects to produce
        table reflection.  Direct usage is like::

            from sqlalchemy import create_engine, MetaData, Table
            from sqlalchemy import inspect

            engine = create_engine('...')
            meta = MetaData()
            user_table = Table('user', meta)
            insp = inspect(engine)
            insp.reflect_table(user_table, None)

        .. versionchanged:: 1.4 Renamed from ``reflecttable`` to
           ``reflect_table``

        :param table: a :class:`~sqlalchemy.schema.Table` instance.
        :param include_columns: a list of string column names to include
          in the reflection process.  If ``None``, all columns are reflected.

        Nc                 3   s(   | ] }| j kr| j |fV  qd S r   )dialect_kwargsr   r   r   tabler   r   r     s   
z*Inspector.reflect_table.<locals>.<genexpr>FT)rU   r)   r-   r@   Zschema_for_objectrK   dictreflection_optionsr`   rp   Z_validate_dialect_kwargsr
   Zpy2kr   strdecodeencodingrf   _reflect_columnrH   r   ZNoSuchTableError_reflect_pk_reflect_fk_reflect_indexes_reflect_unique_constraints_reflect_check_constraints_reflect_table_comment)r   rs   include_columnsexclude_columnsresolve_fks
_extend_onr-   r?   r   rI   ru   Ztbl_optsZfound_tablecols_by_orig_namecol_dr   rr   r   rm     s     

 


 	
    


   zInspector.reflect_tablec                    s   d }|j j| |  |j| |   d }|r>||ksJ|rN||krNd S  d }t fdddD }	d kr|	 d  g }
 dd k	r d }t|tjj	rt
j|dd	}n$t|t
jst
jt d dd	}|
| d
 krt
jf  d
 }|
| d kr0t
jf  d }|
| d krF|  |
 t
j||f|
|	 ||< }|j|jkrvd|_|j|dd d S )NrK   re   c                 3   s"   | ]}| kr| | fV  qd S r   r   rq   r   r   r   r   \  s   z,Inspector._reflect_column.<locals>.<genexpr>)ZnullableZautoincrementquoteinfor#   commentdialect_optionsdefaultT)Z
_reflectedcomputedidentitysequence)Zreplace_existing)metadatadispatchZcolumn_reflectrt   rZ   r   r   r	   elementsZ
TextClause	sa_schemaZDefaultClauseZFetchedValuetextappendZComputedZIdentity_reflect_col_sequenceZColumnr#   primary_keyZappend_column)r   rs   r   r   r   r   	orig_namerK   rg   Zcol_kwcolargsr   r   colr   r   r   ry   I  s\     





 zInspector._reflect_columnc                 C   sT   d|krP|d }t |d dd}d|kr4|d |_d|krF|d |_|| d S )Nr   rK   r   start	increment)r   Sequencer   r   r   )r   r   r   seqr   r   r   r   r     s    

zInspector._reflect_col_sequencec                    sL   | j ||f|j}|rH fdd|d D }|d|j_|j| d S )Nc                    s$   g | ]}| kr|kr | qS r   r   )r   pkr   r   r   r   rL     s    z)Inspector._reflect_pk.<locals>.<listcomp>constrained_columnsrK   )rh   rp   r   r   rK   Z_reload)r   rI   r   rs   r   r   Zpk_consZpk_colsr   r   r   rz     s     zInspector._reflect_pkc
              	      sL  | j ||f|j}
|
D ].}|d } fdd|d D }|rLt||s|r`t||r`q|d }|d }|d }g }|d k	r|rtj||jf|| j|d|	 |D ]}|	d	
|||g qnD|rtj||jf| jtj|d
|	 |D ]}|	d	
||g qd|kr"|d }ni }|tj|||fddi| qd S )NrK   c                    s"   g | ]}| kr | j n|qS r   )r#   )r   cr   r   r   rL     s   z)Inspector._reflect_fk.<locals>.<listcomp>r   referred_schemarM   referred_columns)r   autoload_withr   .)r   r   r   optionsZlink_to_nameT)rT   rp   rS   intersectionrO   r   ZTabler   r)   r   joinZBLANK_SCHEMAappend_constraintZForeignKeyConstraint)r   rI   r   rs   r   r   r   r   r   ru   r[   Zfkey_dconnamer   r   rM   r   Zrefspeccolumnr   r   r   r   r{     s     



zInspector._reflect_fkZascdescZnulls_firstZ
nulls_lastc                 C   sT  |  ||}|D ]<}	|	d }
|	d }|	di }|	d }|	dd}|	di }|	d}|rt||std	|d
|f  q|rqg }|D ]}z||kr|| n|j| }W n, tk
r   td|||f  Y qY nX ||d}| j	D ]\}}||kr||}q|
| qtj|
f|d|itt| d|fg  qd S )NrK   column_namescolumn_sortinguniquere   indexr   Zduplicates_constraintz5Omitting %s key for (%s), key covers omitted columns., z5%s key '%s' was not located in columns for table '%s'r   Z_table)ri   r   rS   issubsetr
   warnr   r   KeyError_index_sort_exprsr   r   ZIndexrt   rV   r   )r   rI   r   rs   r   r   r   ru   ZindexesZindex_drK   columnsr   r   Zflavorr   
duplicatesZidx_colsr   Zidx_colZ	c_sortingr   opr   r   r   r|      s\    




zInspector._reflect_indexesc              
   C   s   z|  ||}W n tk
r&   Y d S X |D ]}	|	d }
|	d }|	d}|rrt||srtdd|  q,|rxq,g }|D ]T}z||kr|| n|j| }W n& t	k
r   td||f  Y qX |
| q|tj|d|
i q,d S )NrK   r   Zduplicates_indexzDOmitting unique constraint key for (%s), key covers omitted columns.r   zDunique constraint key '%s' was not located in columns for table '%s')rj   NotImplementedErrorr   rS   r   r
   r   r   r   r   r   r   r   ZUniqueConstraint)r   rI   r   rs   r   r   r   ru   constraintsconst_dr   r   r   Zconstrained_colsr   Zconstrained_colr   r   r   r}   :  sD    


z%Inspector._reflect_unique_constraintsc           
      C   sH   z|  ||}W n tk
r&   Y d S X |D ]}	|tjf |	 q,d S r   )rl   r   r   r   ZCheckConstraint)
r   rI   r   rs   r   r   r   ru   r   r   r   r   r   r~   m  s    
z$Inspector._reflect_check_constraintsc                 C   s:   z|  ||}W n tk
r&   Y d S X |dd |_d S )Nr   )rk   r   r   r   )r   rI   r   rs   ru   Zcomment_dictr   r   r   r     s
    z Inspector._reflect_table_comment)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)r   TN)>r   
__module____qualname____doc__r
   
deprecatedr*   classmethodr1   r'   r3   r2   r9   r   Z	_inspectsr   r;   r   r<   r   r=   
contextlibcontextmanagerr@   rB   propertyrC   rD   rF   rH   rJ   r]   r^   r_   r`   rb   rc   rd   rf   rh   rT   ri   rj   rk   rl   Zdeprecated_20ro   rm   ry   r   rz   r{   r   Zasc_opZdesc_opZnulls_first_opZnulls_last_opr   r|   r}   r~   r   r   r   r   r   r&   <   s   

	











7




A

$
)


"
   
 BP:3r&   )r   r   baser   r   r    r   r   r	   r
   r   r   r   Zsql.type_apir   r   	decoratorr%   Z_self_inspectsobjectr&   r   r   r   r   <module>   s    
