o
    [h                     @   s   d 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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..
   )Connectable   )exc)
inspection)sql)util)	operators)schema)
TypeEngine)
deprecated)topologicalc                 O   s   | dd }|d u r| ||g|R i |S | jtdd |D tdd | D f}| |}|d u rE| ||g|R i |}|||< |S )N
info_cachec                 s   s     | ]}t |tjr|V  qd S N)
isinstancer   string_types).0a r   /home/ubuntu/experiments/live_experiments/Pythonexperiments/Otree/venv/lib/python3.10/site-packages/sqlalchemy/engine/reflection.py	<genexpr>/   s    zcache.<locals>.<genexpr>c                 s   s$    | ]\}}|d kr||fV  qdS )r   Nr   )r   kvr   r   r   r   0   s   " )get__name__tupleitems)fnselfconargskwr   keyretr   r   r   cache(   s   
r#   c                   @   sf  e Zd ZdZdd Zedd Zee	dd Z
edd	 Zd
d ZejdddGddZdHddZdd Zdd ZdHddZdHddZdHddZdHddZedd dHd!d"ZdHd#d$ZdHd%d&ZdHd'd(ZdHd)d*ZdHd+d,ZdHd-d.Z	/	0	dId1d2Z d3d4 Z!d5d6 Z"d7d8 Z#d9d: Z$d;e%j&fd<e%j'fd=e%j(fd>e%j)fgZ*d?d@ Z+dAdB Z,dCdD Z-dEdF Z.dS )J	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::

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

    The inspection method above is equivalent to using the
    :meth:`_reflection.Inspector.from_engine` method, i.e.::

        engine = create_engine('...')
        insp = Inspector.from_engine(engine)

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

    c                 C   sJ   || _ t|dr|j| _n|| _| j|u r|   | jj| _i | _d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`

        engineN)bindhasattrr%   connectclosedialectr   )r   r&   r   r   r   __init__U   s   




zInspector.__init__c                 C   s    t |jdr|j|S t|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`.

        	inspector)r'   r*   r,   r$   )clsr&   r   r   r   from_engineq   s   zInspector.from_enginec                 C   s
   t | S r   )r$   r.   )r&   r   r   r   _insp   s   
zInspector._inspc                 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   r0      s   	zInspector.default_schema_namec                 C   s$   t | jdr| jj| j| jdS g S )zReturn all schema names.get_schema_namesr   )r'   r*   r2   r&   r   r1   r   r   r   r2      s
   zInspector.get_schema_names)z1.0a	  The :paramref:`get_table_names.order_by` parameter is deprecated and will be removed in a future release.  Please refer to :meth:`_reflection.Inspector.get_sorted_table_and_fkc_names` for a more comprehensive solution to resolving foreign key cycles between tables.)order_byNc                 C   s   t | jdr| jj| j|| jd}n| j|}|dkrCg }|D ]}| ||D ]}||d kr9||d |f q(q t	t
||}|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`.

        :param order_by: Optional, may be the string "foreign_key" to sort
         the result on foreign key dependencies.  Does not automatically
         resolve cycles, and will raise :class:`.CircularDependencyError`
         if cycles exist.

        .. seealso::

            :meth:`_reflection.Inspector.get_sorted_table_and_fkc_names`

            :attr:`_schema.MetaData.sorted_tables`

        get_table_namesr3   Zforeign_keyreferred_table)r'   r*   r5   r&   r   r%   table_namesget_foreign_keysappendlistr   sort)r   r	   r4   tnamestuplestnamefkeyr   r   r   r5      s   '
zInspector.get_table_namesc           	   
      s8  t | jdr| jj| j|| jd}n| j|}t }t i |D ]'}| ||}tdd |D |< |D ]}||d krH|	|d |f q7q"z
t
t||}W n6 tjy } z)|jD ] |   fdd d  D  q`t
t||}W Y d	}~nd	}~ww 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`.

        r5   r3   c                 S   s   g | ]}|d  qS )namer   )r   Zfkr   r   r   
<listcomp>   s    z<Inspector.get_sorted_table_and_fkc_names.<locals>.<listcomp>r6   c                 3   s    | ]	} d  |fV  qdS )r   Nr   )r   Zfkc)edger   r   r     s    
z;Inspector.get_sorted_table_and_fkc_names.<locals>.<genexpr>r   Nc                    s   g | ]}| |  fqS r   )
difference)r   r>   )fknames_for_tableremaining_fkcsr   r   rA   
  s    )r'   r*   r5   r&   r   r%   r7   setr8   addr:   r   r;   r   ZCircularDependencyErroredgesremoveupdate)	r   r	   r<   r=   r>   fkeysr?   Zcandidate_sorterrr   )rB   rD   rE   r   get_sorted_table_and_fkc_names   s@   




z(Inspector.get_sorted_table_and_fkc_namesc                 C      | j j| j| j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

        r3   )r*   get_temp_table_namesr&   r   r1   r   r   r   rO        	zInspector.get_temp_table_namesc                 C   rN   )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

        r3   )r*   get_temp_view_namesr&   r   r1   r   r   r   rQ     rP   zInspector.get_temp_view_namesc                 K   s0   t | jdr| jj| j||fd| ji|S 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*   rR   r&   r   r   
table_namer	   r    r   r   r   rR   )  s   zInspector.get_table_optionsc                 C   s   | j j| j|| j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`.

        r3   )r*   get_view_namesr&   r   )r   r	   r   r   r   rU   =  s   
zInspector.get_view_namesc                 C   s   | j j| j||| jdS )zReturn definition for `view_name`.

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

        r3   )r*   get_view_definitionr&   r   )r   Z	view_namer	   r   r   r   rV   I  s   zInspector.get_view_definitionc                 K   sJ   | j j| j||fd| ji|}|D ]}|d }t|ts"| |d< q|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.

        * ``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*   get_columnsr&   r   r   r
   )r   rT   r	   r    Zcol_defsZcol_defcoltyper   r   r   rX   U  s   1

zInspector.get_columnsz0.7zThe :meth:`_reflection.Inspector.get_primary_keys` method is deprecated and will be removed in a future release.  Please refer to the :meth:`_reflection.Inspector.get_pk_constraint` method.c                 K   s$   | j j| j||fd| ji|d S )zReturn information about primary keys in `table_name`.

        Given a string `table_name`, and an optional string `schema`, return
        primary key information as a list of column names.
        r   constrained_columnsr*   get_pk_constraintr&   r   rS   r   r   r   get_primary_keys  s   zInspector.get_primary_keysc                 K       | j j| j||fd| ji|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   r[   rS   r   r   r   r\     s   zInspector.get_pk_constraintc                 K   r^   )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   )r*   r8   r&   r   rS   r   r   r   r8     s   zInspector.get_foreign_keysc                 K   r^   )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``, ``nullsfirst``, ``nullslast``.

          .. 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   )r*   get_indexesr&   r   rS   r   r   r   r_     s   $zInspector.get_indexesc                 K   r^   )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   )r*   get_unique_constraintsr&   r   rS   r   r   r   r`     s   z Inspector.get_unique_constraintsc                 K   r^   )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   )r*   get_table_commentr&   r   rS   r   r   r   ra     s   zInspector.get_table_commentc                 K   r^   )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   )r*   get_check_constraintsr&   r   rS   r   r   r   rb   2  s   zInspector.get_check_constraintsr   Tc              
      sp  |dur |v r
dS |   | jj}| j } j}t fdd|jD }	| j||fi  j}
|
r: 	|
 t
jrSt|trH||j}t|trS||j}d}i }| j||fi  jD ]}d}|  |||| qb|sxt j| || || | || |||||	 | || ||||	 | || ||||	 | || ||||	 | || |	 dS )a  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.engine.reflection import Inspector

            engine = create_engine('...')
            meta = MetaData()
            user_table = Table('user', meta)
            insp = Inspector.from_engine(engine)
            insp.reflecttable(user_table, None)

        :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 v r| j |fV  qd S r   )dialect_kwargsr   r   r   tabler   r   r     s    
z)Inspector.reflecttable.<locals>.<genexpr>FT)rG   r&   r*   Zschema_for_objectr@   dictreflection_optionsrR   rc   Z_validate_dialect_kwargsr   Zpy2kr   strdecodeencodingrX   _reflect_columnr   ZNoSuchTableError_reflect_pk_reflect_fk_reflect_indexes_reflect_unique_constraints_reflect_check_constraints_reflect_table_comment)r   rf   include_columnsexclude_columnsresolve_fks
_extend_onr*   r	   rT   rh   Ztbl_optsZfound_tablecols_by_orig_namecol_dr   re   r   reflecttableS  s   








zInspector.reflecttablec                    sR   d }|j | |   d }|r||vs|r||v rd S  d }t fdddD }	d v r8|	 d  g }
 dd urk d }t|tjjrTt	j
|dd	}nt|t	jsft	j
t d dd	}|
| d
 v r~t	jdi  d
 }|
| d v r|  |
 t	j||g|
R i |	 ||< }|j|jv rd|_|| d S )Nr@   rW   c                 3   s$    | ]}| v r| | fV  qd S r   r   rd   rx   r   r   r     s    
	z,Inspector._reflect_column.<locals>.<genexpr>)ZnullableZautoincrementquoteinfor!   commentdialect_optionsdefaultT)Z
_reflectedcomputedsequencer   )dispatchZcolumn_reflectrg   rJ   r   r   r   elementsZ
TextClause	sa_schemaZDefaultClauseZFetchedValuetextr9   ZComputed_reflect_col_sequenceColumnr!   primary_keyappend_column)r   rf   rx   rs   rt   rw   Z	orig_namer@   rY   Zcol_kwcolargsr   r   colr   rz   r   rl     sN   

zInspector._reflect_columnc                 C   sX   d|v r*|d }t |d dd}d|v r|d |_d|v r#|d |_|| d S d S )Nr   r@   r   start	increment)r   Sequencer   r   r9   )r   rx   r   seqr   r   r   r   r     s   

zInspector._reflect_col_sequencec                    sT   | j ||fi |j}|r( fdd|d D }|d|j_|j| d S d S )Nc                    s$   g | ]}| v r|vr | qS r   r   )r   pkrw   rt   r   r   rA   (  s
    z)Inspector._reflect_pk.<locals>.<listcomp>rZ   r@   )r\   rc   r   r   r@   Z_reload)r   rT   r	   rf   rw   rt   Zpk_consZpk_colsr   r   r   rm   !  s   zInspector._reflect_pkc	              	      s>  | j ||fi |j}	|	D ]}
|
d } fdd|
d D }|r(t||r(q|
d }|
d }|
d }g }|d ur^|rMtj||jfd|| j|d	| |D ]}|d
	|||g qOn#|rrtj||jfd| jtj
|d| |D ]}|d
	||g qtd|
v r|
d }ni }|tj|||fddi| qd S )Nr@   c                    s"   g | ]}| v r | j n|qS r   )r!   )r   crw   r   r   rA   G  s    z)Inspector._reflect_fk.<locals>.<listcomp>rZ   referred_schemar6   referred_columnsT)autoloadr	   autoload_withrv   .)r   r   r	   rv   optionsZlink_to_name)r8   rc   rF   intersectionr   Tablemetadatar&   r9   joinZBLANK_SCHEMAappend_constraintZForeignKeyConstraint)r   rT   r	   rf   rw   rt   ru   rv   rh   rK   Zfkey_dconnamerZ   r   r6   r   Zrefspeccolumnr   r   r   r   rn   5  s   
		
zInspector._reflect_fkascZdescZ
nullsfirstZ	nullslastc                 C   sN  |  ||}|D ]}	|	d }
|	d }|	di }|	d }|	dd}|	di }|	d}|rCt||sCtd	|d
|f  q|rFqg }|D ]@}z||v rU|| n|j| }W n tyn   td|||f  Y qJw ||d}| j	D ]\}}||v r||}qx|
| qJtj|
g|R d|itt| d|fg  qd S )Nr@   column_namescolumn_sortinguniquerW   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   _table)r_   r   rF   issubsetr   warnr   r   KeyError_index_sort_exprsr9   r   Indexrg   r:   r   )r   rT   r	   rf   rw   rs   rt   rh   ZindexesZindex_dr@   columnsr   r   Zflavorr~   
duplicatesZidx_colsr   Zidx_colZ	c_sortingr   opr   r   r   ro     sb   
zInspector._reflect_indexesc              
   C   s   z|  ||}W n
 ty   Y d S w |D ]_}	|	d }
|	d }|	d}|r8t||s8tdd|  q|r;qg }|D ])}z||v rJ|| n|j| }W n t	yb   td||f  Y q?w |
| q?|tj|d|
i qd S )Nr@   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')r`   NotImplementedErrorr   rF   r   r   r   r   r   r   r9   r   r   ZUniqueConstraint)r   rT   r	   rf   rw   rs   rt   rh   constraintsconst_dr   r   r   Zconstrained_colsr   Zconstrained_colr   r   r   rp     sJ   
z%Inspector._reflect_unique_constraintsc           
      C   sJ   z|  ||}W n
 ty   Y d S w |D ]}	|tjdi |	 qd S )Nr   )rb   r   r   r   ZCheckConstraint)
r   rT   r	   rf   rw   rs   rt   rh   r   r   r   r   r   rq     s   
z$Inspector._reflect_check_constraintsc                 C   s8   z|  ||}W n
 ty   Y d S w |dd |_d S )Nr   )ra   r   r   r}   )r   rT   r	   rf   rh   Zcomment_dictr   r   r   rr     s   z Inspector._reflect_table_comment)NNr   )r   TN)/r   
__module____qualname____doc__r+   classmethodr.   r   Z	_inspectsr   r/   propertyr0   r2   r   Zdeprecated_paramsr5   rM   rO   rQ   rR   rU   rV   rX   r   r]   r\   r8   r_   r`   ra   rb   ry   rl   r   rm   rn   r   Zasc_opZdesc_opZnullsfirst_opZnullslast_opr   ro   rp   rq   rr   r   r   r   r   r$   9   sd    



	
+8



;


#
(

%
 =I:3r$   N)r   baser    r   r   r   r   r   r	   r   Zsql.type_apir
   r   r   	decoratorr#   objectr$   r   r   r   r   <module>   s   
