B 4]?@sdZddlmZddlmZddlmZddlmZddlmZddlmZdd lm Z dd l m Z dd lm Z dd lmZejd dZGdddeZdS)aProvides 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) topologicalcOs|dd}|dkr&|||f||S|jtdd|Dtdd|Df}||}|dkr~|||f||}|||<|S)N info_cachecss|]}t|tjr|VqdS)N) isinstancer string_types).0arO/opt/alt/python37/lib64/python3.7/site-packages/sqlalchemy/engine/reflection.py /szcache..css2|]*\}}t|tjtjtfr||fVqdS)N)rrrZ int_typesfloat)rkvrrrr1s)get__name__tupleitems)fnselfZconargskwr keyZretrrrcache(s  r!c@s`eZdZdZddZeddZee ddZ e dd Z d d Z ejd d dGddZdHddZddZddZdIddZdJddZdKddZdLddZedd dMd!d"ZdNd#d$ZdOd%d&ZdPd'd(ZdQd)d*ZdRd+d,ZdSd-d.ZdTd1d2Z d3d4Z!d5d6Z"d7d8Z#d9d:Z$d;e%j&fde%j)fgZ*d?d@Z+dAdBZ,dCdDZ-dEdFZ.dS)U InspectoramPerforms 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:`.Inspector` object is usually created via the :func:`.inspect` function:: from sqlalchemy import inspect, create_engine engine = create_engine('...') insp = inspect(engine) The inspection method above is equivalent to using the :meth:`.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:`.Inspector` subclass that provides additional methods specific to the dialect's target database. cCsJ||_t|dr|j|_n||_|j|kr6||jj|_i|_dS)ajInitialize a new :class:`.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:`.Inspector`, see :meth:`.Inspector.from_engine` engineN)bindhasattrr#Zconnectclosedialectr )rr$rrr__init__Xs      zInspector.__init__cCs t|jdr|j|St|S)aConstruct 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:`.Inspector` in that the :class:`~sqlalchemy.engine.interfaces.Dialect` is given a chance to provide a dialect-specific :class:`.Inspector` instance, which may provide additional methods. See the example at :class:`.Inspector`. inspector)r%r'r)r")clsr$rrr from_enginets  zInspector.from_enginecCs t|S)N)r"r+)r$rrr_inspszInspector._inspcCs|jjS)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)rrrrr-s zInspector.default_schema_namecCs$t|jdr |jj|j|jdSgS)z!Return all schema names. get_schema_names)r )r%r'r.r$r )rrrrr.s zInspector.get_schema_names)z1.0zThe :paramref:`get_table_names.order_by` parameter is deprecated and will be removed in a future release. Please refer to :meth:`.Inspector.get_sorted_table_and_fkc_names` for a more comprehensive solution to resolving foreign key cycles between tables.)order_byNcCst|jdr$|jj|j||jd}n |j|}|dkrg}x@|D]8}x2|||D]"}||dkrT||d|fqTWqBWt t ||}|S)aReturn 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:`.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:`.Inspector.get_sorted_table_and_fkc_names` :attr:`.MetaData.sorted_tables` get_table_names)r Z foreign_keyreferred_table) r%r'r0r$r r# table_namesget_foreign_keysappendlistr sort)rr r/tnamestuplestnamefkeyrrrr0s%    zInspector.get_table_namesc sDt|jdr$|jj|j||jd}n |j|}t}tixZ|D]R}|||}tdd|D|<x*|D]"}||dkrr| |d|fqrWqFWyt t ||}Wnpt jk r }zNx8|jD].|fdddDqWt t ||}Wd d }~XYnXfd d|Dd t fgS) axReturn 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:`.Inspector.get_table_names` :func:`.sort_tables_and_constraints` - similar method which works with an already-given :class:`.MetaData`. r0)r cSsg|] }|dqS)namer)rZfkrrr sz.r1c3s|]}d|fVqdS)rNr)rZfkc)edgerrrsz;Inspector.get_sorted_table_and_fkc_names..rNcsg|]}||fqSr) difference)rr9)fknames_for_tableremaining_fkcsrrr< s)r%r'r0r$r r#r2setr3addr5r r6rZCircularDependencyErrorZedgesremoveupdate) rr r7r8r9fkeysr:Zcandidate_sorterrr)r=r?r@rget_sorted_table_and_fkc_namess0         " z(Inspector.get_sorted_table_and_fkc_namescCs|jj|j|jdS)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 )r )r'get_temp_table_namesr$r )rrrrrHs zInspector.get_temp_table_namescCs|jj|j|jdS)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 )r )r'get_temp_view_namesr$r )rrrrrIs zInspector.get_temp_view_namescKs0t|jdr,|jj|j||fd|ji|SiS)aReturn 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'rJr$r )r table_namer rrrrrJ*s zInspector.get_table_optionscCs|jj|j||jdS)zReturn all view names in `schema`. :param schema: Optional, retrieve names from a non-default schema. For special quoting, use :class:`.quoted_name`. )r )r'get_view_namesr$r )rr rrrrL>szInspector.get_view_namescCs|jj|j|||jdS)zReturn definition for `view_name`. :param schema: Optional, retrieve names from a non-default schema. For special quoting, use :class:`.quoted_name`. )r )r'get_view_definitionr$r )rZ view_namer rrrrMJszInspector.get_view_definitioncKsN|jj|j||fd|ji|}x(|D] }|d}t|ts&||d<q&W|S)aReturn 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. * ``attrs`` - dict containing optional column attributes :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 rr )rrKr rZcol_defsZcol_defcoltyperrrrOVs  zInspector.get_columnsz0.7zThe :meth:`.Inspector.get_primary_keys` method is deprecated and will be removed in a future release. Please refer to the :meth:`.Inspector.get_pk_constraint` method.cKs$|jj|j||fd|ji|dS)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 )rrKr rrrrget_primary_keys~s zInspector.get_primary_keyscKs |jj|j||fd|ji|S)aReturn 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'rRr$r )rrKr rrrrrRszInspector.get_pk_constraintcKs |jj|j||fd|ji|S)aReturn 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'r3r$r )rrKr rrrrr3szInspector.get_foreign_keyscKs |jj|j||fd|ji|S)aReturn 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 )rrKr rrrrrTs$zInspector.get_indexescKs |jj|j||fd|ji|S)aoReturn 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 )rrKr rrrrrUsz Inspector.get_unique_constraintscKs |jj|j||fd|ji|S)aReturn 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 )rrKr rrrrrV szInspector.get_table_commentcKs |jj|j||fd|ji|S)aReturn 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 :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 )rrKr rrrrrWszInspector.get_check_constraintsrTc sl|dk r|krdS||jj}|j}j}tfdd|jD} |j||fj} | rp | t j rt |t r||j}t |t r||j}d} i} x0|j||fjD]} d} || ||| qW| stj|||| ||||| |||| |||| ||| |||| ||| |||| ||| |||| dS)a Given a 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. Nc3s(|] }|jkr|j|fVqdS)N)dialect_kwargsr)rr)tablerrrhsz)Inspector.reflecttable..FT)rBr$r'Zschema_for_objectr;dictreflection_optionsrJrXZ_validate_dialect_kwargsrZpy2krstrdecodeencodingrO_reflect_columnrZNoSuchTableError _reflect_pk _reflect_fk_reflect_indexes_reflect_unique_constraints_reflect_check_constraints_reflect_table_comment)rrYinclude_columnsexclude_columns resolve_fks _extend_onr'r rKr[Ztbl_optsZ found_tablecols_by_orig_namecol_dr)rYr reflecttable:s           zInspector.reflecttablec s(d}|j||d}|r,||ks8|r<||kr.)ZnullableZ autoincrementZquoteinfor commentdialect_optionsdefaultT)Z _reflectedsequence)dispatchZcolumn_reflectrZrDrrrelementsZ TextClause sa_schemaZ DefaultClauseZ FetchedValuetextr4_reflect_col_sequenceZColumnr primary_keyZ append_column) rrYrkrfrgrjZ orig_namer;rPZcol_kwcolargsrpcolr)rkrr_s8       zInspector._reflect_columncCsTd|krP|d}t|ddd}d|kr4|d|_d|krF|d|_||dS)Nrqr;rstart increment)rtSequencerzr{r4)rrkrxseqrqrrrrvs  zInspector._reflect_col_sequencecsL|j||f|j}|rHfdd|dD}|d|j_|j|dS)Ncs$g|]}|kr|kr|qSrr)rZpk)rjrgrrr< sz)Inspector._reflect_pk..rQr;)rRrXrrwr;Z_reload)rrKr rYrjrgZpk_consZpk_colsr)rjrgrr`s  zInspector._reflect_pkc  sL|j||f|j} x2| D](} | d} fdd| dD} |rRt| |rRq| d} | d}| d}g}| dk r|rtj||jfd| |j|d |xn|D]}|d | ||gqWnJ|rtj||jfd|jtj |d |x |D]}|d ||gqWd | kr | d }ni}| tj | || fd di|qWdS)Nr;cs"g|]}|kr|jn|qSr)r )rc)rjrrr<+sz)Inspector._reflect_fk..rQreferred_schemar1referred_columnsT)autoloadr autoload_withri.)rrr rioptionsZ link_to_name) r3rXrA intersectionrtZTableZmetadatar$r4joinZ BLANK_SCHEMAappend_constraintZForeignKeyConstraint)rrKr rYrjrgrhrir[rEZfkey_dconnamerQrr1rZrefspeccolumnrr)rjrras^        zInspector._reflect_fkZascZdescZ nullsfirstZ nullslastc Cs`|||}xL|D]B} | d} | d} | di} | d} | dd}| di}| d}|rt| |std |d | fq|rqg}x| D]}y||kr||n|j|}Wn*tk rtd |||fwYnX| |d }x"|j D]\}}||kr||}qW| |qWt j | f|d |it t|d| fgqWdS)Nr; column_namescolumn_sortinguniquerNindexroZduplicates_constraintz5Omitting %s key for (%s), key covers omitted columns.z, z5%s key '%s' was not located in columns for table '%s'rZ_table)rTrrAissubsetrwarnrr~KeyError_index_sort_exprsr4rtZIndexrZr5r)rrKr rYrjrfrgr[ZindexesZindex_dr;columnsrrZflavorro duplicatesZidx_colsr~Zidx_colZ c_sortingroprrrrbgsH        zInspector._reflect_indexesc Csy|||}Wntk r$dSXx|D]} | d} | d} | d} |rrt| |srtdd| q,| rxq,g} x\| D]T}y||kr||n|j|}Wn&t k rtd||fYqX| |qW| t j | d| iq,WdS)Nr;rZduplicates_indexzDOmitting unique constraint key for (%s), key covers omitted columns.z, zDunique constraint key '%s' was not located in columns for table '%s')rUNotImplementedErrorrrArrrrr~rr4rrtZUniqueConstraint)rrKr rYrjrfrgr[ constraintsconst_drrrZconstrained_colsr~Zconstrained_colrrrrcs6    z%Inspector._reflect_unique_constraintsc CsJy|||}Wntk r$dSXx|D]} |tjf| q,WdS)N)rWrrrtZCheckConstraint) rrKr rYrjrfrgr[rrrrrrds  z$Inspector._reflect_check_constraintscCs8y|||}Wntk r$dSX|dd|_dS)Nru)rVrrrn)rrKr rYr[Z comment_dictrrrres z Inspector._reflect_table_comment)NN)N)N)N)N)N)N)N)N)N)N)N)N)rTN)/r __module__ __qualname____doc__r( classmethodr+rZ _inspectsrr,propertyr-r.rZdeprecated_paramsr0rGrHrIrJrLrMrOr rSrRr3rTrUrVrWrlr_rvr`rarZasc_opZdesc_opZ nullsfirst_opZ nullslast_oprrbrcrdrerrrrr"=sT    * 8   (  # (    9 I :3r"N)rbaserrrrrrr rtZ sql.type_apir r r Z decoratorr!objectr"rrrrs