Reflecting Database Objects

A Table object can be instructed to loadinformation about itself from the corresponding database schema object alreadyexisting within the database. This process is called reflection. In themost simple case you need only specify the table name, a MetaDataobject, and the autoload=True flag. If theMetaData is not persistently bound, also add theautoload_with argument:

  1. >>> messages = Table('messages', meta, autoload=True, autoload_with=engine)
  2. >>> [c.name for c in messages.columns]
  3. ['message_id', 'message_name', 'date']

The above operation will use the given engine to query the database forinformation about the messages table, and will then generateColumn, ForeignKey,and other objects corresponding to this information as though theTable object were hand-constructed in Python.

When tables are reflected, if a given table references another one via foreignkey, a second Table object is created within theMetaData object representing the connection.Below, assume the table shopping_cart_items references a table namedshopping_carts. Reflecting the shopping_cart_items table has theeffect such that the shopping_carts table will also be loaded:

  1. >>> shopping_cart_items = Table('shopping_cart_items', meta, autoload=True, autoload_with=engine)
  2. >>> 'shopping_carts' in meta.tables:
  3. True

The MetaData has an interesting “singleton-like”behavior such that if you requested both tables individually,MetaData will ensure that exactly oneTable object is created for each distinct tablename. The Table constructor actually returns toyou the already-existing Table object if onealready exists with the given name. Such as below, we can access the alreadygenerated shopping_carts table just by naming it:

  1. shopping_carts = Table('shopping_carts', meta)

Of course, it’s a good idea to use autoload=True with the above tableregardless. This is so that the table’s attributes will be loaded if they havenot been already. The autoload operation only occurs for the table if ithasn’t already been loaded; once loaded, new calls toTable with the same name will not re-issue anyreflection queries.

Overriding Reflected Columns

Individual columns can be overridden with explicit values when reflectingtables; this is handy for specifying custom datatypes, constraints such asprimary keys that may not be configured within the database, etc.:

  1. >>> mytable = Table('mytable', meta,
  2. ... Column('id', Integer, primary_key=True), # override reflected 'id' to have primary key
  3. ... Column('mydata', Unicode(50)), # override reflected 'mydata' to be Unicode
  4. ... # additional Column objects which require no change are reflected normally
  5. ... autoload_with=some_engine)

See also

Working with Custom Types and Reflection - illustrates how the abovecolumn override technique applies to the use of custom datatypes withtable reflection.

Reflecting Views

The reflection system can also reflect views. Basic usage is the same as thatof a table:

  1. my_view = Table("some_view", metadata, autoload=True)

Above, my_view is a Table object withColumn objects representing the names and types ofeach column within the view “some_view”.

Usually, it’s desired to have at least a primary key constraint whenreflecting a view, if not foreign keys as well. View reflection doesn’textrapolate these constraints.

Use the “override” technique for this, specifying explicitly those columnswhich are part of the primary key or have foreign key constraints:

  1. my_view = Table("some_view", metadata,
  2. Column("view_id", Integer, primary_key=True),
  3. Column("related_thing", Integer, ForeignKey("othertable.thing_id")),
  4. autoload=True
  5. )

Reflecting All Tables at Once

The MetaData object can also get a listing oftables and reflect the full set. This is achieved by using thereflect() method. After calling it, alllocated tables are present within the MetaDataobject’s dictionary of tables:

  1. meta = MetaData()
  2. meta.reflect(bind=someengine)
  3. users_table = meta.tables['users']
  4. addresses_table = meta.tables['addresses']

metadata.reflect() also provides a handy way to clear or delete all the rows in a database:

  1. meta = MetaData()
  2. meta.reflect(bind=someengine)
  3. for table in reversed(meta.sorted_tables):
  4. someengine.execute(table.delete())

Fine Grained Reflection with Inspector

A low level interface which provides a backend-agnostic system of loadinglists of schema, table, column, and constraint descriptions from a givendatabase is also available. This is known as the “Inspector”:

  1. from sqlalchemy import create_engine
  2. from sqlalchemy.engine import reflection
  3. engine = create_engine('...')
  4. insp = reflection.Inspector.from_engine(engine)
  5. print(insp.get_table_names())
  • class sqlalchemy.engine.reflection.Inspector(bind)
  • Performs database schema inspection.

The Inspector acts as a proxy to the reflection methods of theDialect, providing aconsistent interface as well as caching support for previouslyfetched metadata.

A Inspector object is usually created via theinspect() function:

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

The inspection method above is equivalent to using theInspector.from_engine() method, i.e.:

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

Where above, the Dialect may optto return an Inspector subclass that provides additionalmethods specific to the dialect’s target database.

For a dialect-specific instance of Inspector, seeInspector.from_engine()

  • property default_schema_name
  • Return the default schema name presented by the dialectfor the current engine’s database user.

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

  • classmethod fromengine(_bind)
  • Construct a new dialect-specific Inspector object from the givenengine or connection.

This method differs from direct a direct constructor call ofInspector in that theDialect is given a chance toprovide a dialect-specific Inspector instance, which mayprovide additional methods.

See the example at Inspector.

  • getcheck_constraints(_table_name, schema=None, **kw)
  • Return information about check constraints in table_name.

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

  1. - name
  2. -

the check constraint’s name

  1. - sqltext
  2. -

the check constraint’s SQL expression

  1. - dialect_options
  2. -

may or may not be present; a dictionary with additionaldialect-specific options for this CHECK constraint

New in version 1.3.8.

  1. - Parameters
  2. -
  3. -

table_name – string name of the table. For special quoting,use quoted_name.

  1. -

schema – string schema name; if omitted, uses the default schemaof the database connection. For special quoting,use quoted_name.

New in version 1.1.0.

  • getcolumns(_table_name, schema=None, **kw)
  • Return information about columns in table_name.

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

  1. -

name - the column’s name

  1. -

type - the type of this column; an instance ofTypeEngine

  1. -

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

  1. -

default - the column’s server default value - this is returnedas a string SQL expression.

  1. -

attrs - dict containing optional column attributes

  1. - Parameters
  2. -
  3. -

table_name – string name of the table. For special quoting,use quoted_name.

  1. -

schema – string schema name; if omitted, uses the default schemaof the database connection. For special quoting,use quoted_name.

  1. - Returns
  2. -

list of dictionaries, each representing the definition ofa database column.

  • getforeign_keys(_table_name, schema=None, **kw)
  • Return information about foreignkeys in _table_name.

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

  1. - constrained_columns
  2. -

a list of column names that make up the foreign key

  1. - referred_schema
  2. -

the name of the referred schema

  1. - referred_table
  2. -

the name of the referred table

  1. - referred_columns
  2. -

a list of column names in the referred table that correspond toconstrained_columns

  1. - name
  2. -

optional name of the foreign key constraint.

  1. - Parameters
  2. -
  3. -

table_name – string name of the table. For special quoting,use quoted_name.

  1. -

schema – string schema name; if omitted, uses the default schemaof the database connection. For special quoting,use quoted_name.

  • getindexes(_table_name, schema=None, **kw)
  • Return information about indexes in table_name.

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

  1. - name
  2. -

the index’s name

  1. - column_names
  2. -

list of column names in order

  1. - unique
  2. -

boolean

  1. - column_sorting
  2. -

optional dict mapping column names to tuple of sort keywords,which may include asc, desc, nullsfirst, nullslast.

New in version 1.3.5.

  1. - dialect_options
  2. -

dict of dialect-specific index options. May not be presentfor all dialects.

New in version 1.0.0.

  1. - Parameters
  2. -
  3. -

table_name – string name of the table. For special quoting,use quoted_name.

  1. -

schema – string schema name; if omitted, uses the default schemaof the database connection. For special quoting,use quoted_name.

  • getpk_constraint(_table_name, schema=None, **kw)
  • Return information about primary key constraint on table_name.

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

  1. - constrained_columns
  2. -

a list of column names that make up the primary key

  1. - name
  2. -

optional name of the primary key constraint.

  1. - Parameters
  2. -
  3. -

table_name – string name of the table. For special quoting,use quoted_name.

  1. -

schema – string schema name; if omitted, uses the default schemaof the database connection. For special quoting,use quoted_name.

  • getprimary_keys(_table_name, schema=None, **kw)
  • Return information about primary keys in table_name.

Deprecated since version 0.7: The Inspector.get_primary_keys() method is deprecated and will be removed in a future release. Please refer to the Inspector.get_pk_constraint() method.

Given a string table_name, and an optional string schema, returnprimary key information as a list of column names.

  • get_schema_names()
  • Return all schema names.

  • getsorted_table_and_fkc_names(_schema=None)

  • Return dependency-sorted table and foreign key constraint names inreferred 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 keyconstraint names that are not detected as belonging to a cycle.The final elementwill be (None, [(tname, fkname), (tname, fkname), ..])which will consist of remainingforeign key constraint names that would require a separate CREATEstep after-the-fact, based on dependencies between tables.

New in version 1.0.-.

See also

Inspector.get_table_names()

  1. - [<code>sort_tables_and_constraints()</code>]($2c8d2fcf7fd7d939.md#sqlalchemy.schema.sort_tables_and_constraints) - similar method which works
  2. -

with an already-given MetaData.

  • gettable_comment(_table_name, schema=None, **kw)
  • 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:

  1. - text
  2. -

text of the comment.

Raises NotImplementedError for a dialect that does not supportcomments.

New in version 1.2.

  • gettable_names(_schema=None, order_by=None)
  • 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 Inspector.get_view_names()method.

  1. - Parameters
  2. -
  3. -

schema – Schema name. If schema is left at None, thedatabase’s default schema isused, else the named schema is searched. If the database does notsupport named schemas, behavior is undefined if schema is notpassed as None. For special quoting, use quoted_name.

  1. -

order_by

Optional, may be the string “foreign_key” to sortthe result on foreign key dependencies. Does not automaticallyresolve cycles, and will raise CircularDependencyErrorif cycles exist.

Deprecated since version 1.0: The get_table_names.order_by parameter is deprecated and will be removed in a future release. Please refer to Inspector.get_sorted_table_and_fkc_names() for a more comprehensive solution to resolving foreign key cycles between tables.

See also

Inspector.get_sorted_table_and_fkc_names()

MetaData.sorted_tables

  • gettable_options(_table_name, schema=None, **kw)
  • Return a dictionary of options specified when the table of thegiven name was created.

This currently includes some options that apply to MySQL tables.

  1. - Parameters
  2. -
  3. -

table_name – string name of the table. For special quoting,use quoted_name.

  1. -

schema – string schema name; if omitted, uses the default schemaof the database connection. For special quoting,use quoted_name.

  • get_temp_table_names()
  • return a list of temporary table names for the current bind.

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

New in version 1.0.0.

  • get_temp_view_names()
  • return a list of temporary view names for the current bind.

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

New in version 1.0.0.

  • getunique_constraints(_table_name, schema=None, **kw)
  • Return information about unique constraints in table_name.

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

  1. - name
  2. -

the unique constraint’s name

  1. - column_names
  2. -

list of column names in order

  1. - Parameters
  2. -
  3. -

table_name – string name of the table. For special quoting,use quoted_name.

  1. -

schema – string schema name; if omitted, uses the default schemaof the database connection. For special quoting,use quoted_name.

  • getview_definition(_view_name, schema=None)
  • Return definition for view_name.

    • Parameters
    • schema – Optional, retrieve names from a non-default schema.For special quoting, use quoted_name.
  • getview_names(_schema=None)

  • Return all view names in schema.

    • Parameters
    • schema – Optional, retrieve names from a non-default schema.For special quoting, use quoted_name.
  • reflecttable(table, include_columns, exclude_columns=(), resolve_fks=True, _extend_on=None)

  • Given a Table object, load its internal constructs based onintrospection.

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

  1. from sqlalchemy import create_engine, MetaData, Table
  2. from sqlalchemy.engine.reflection import Inspector
  3.  
  4. engine = create_engine('...')
  5. meta = MetaData()
  6. user_table = Table('user', meta)
  7. insp = Inspector.from_engine(engine)
  8. insp.reflecttable(user_table, None)
  1. - Parameters
  2. -
  3. -

table – a Table instance.

  1. -

include_columns – a list of string column names to includein the reflection process. If None, all columns are reflected.

Limitations of Reflection

It’s important to note that the reflection process recreates Tablemetadata using only information which is represented in the relational database.This process by definition cannot restore aspects of a schema that aren’tactually stored in the database. State which is not available from reflectionincludes but is not limited to:

  • Client side defaults, either Python functions or SQL expressions defined usingthe default keyword of Column (note this is separate from server_default,which specifically is what’s available via reflection).

  • Column information, e.g. data that might have been placed into theColumn.info dictionary

  • The value of the .quote setting for Column or Table

  • The association of a particular Sequence with a given Column

The relational database also in many cases reports on table metadata in adifferent format than what was specified in SQLAlchemy. The Tableobjects returned from reflection cannot be always relied upon to produce the identicalDDL as the original Python-defined Table objects. Areas wherethis occurs includes server defaults, column-associated sequences and variousidiosyncrasies regarding constraints and datatypes. Server side defaults maybe returned with cast directives (typically PostgreSQL will include a ::<type>cast) or different quoting patterns than originally specified.

Another category of limitation includes schema structures for which reflectionis only partially or not yet defined. Recent improvements to reflection allowthings like views, indexes and foreign key options to be reflected. As of thiswriting, structures like CHECK constraints, table comments, and triggers arenot reflected.