~ubuntu-branches/debian/jessie/sqlalchemy/jessie

« back to all changes in this revision

Viewing changes to doc/build/core/reflection.rst

  • Committer: Package Import Robot
  • Author(s): Piotr Ożarowski
  • Date: 2013-10-28 22:29:40 UTC
  • mfrom: (1.4.24)
  • Revision ID: package-import@ubuntu.com-20131028222940-wvyqffl4g617caun
Tags: 0.8.3-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
.. _metadata_reflection_toplevel:
 
2
.. _metadata_reflection:
 
3
 
 
4
.. module:: sqlalchemy.schema
 
5
 
 
6
 
 
7
Reflecting Database Objects
 
8
===========================
 
9
 
 
10
A :class:`~sqlalchemy.schema.Table` object can be instructed to load
 
11
information about itself from the corresponding database schema object already
 
12
existing within the database. This process is called *reflection*. In the
 
13
most simple case you need only specify the table name, a :class:`~sqlalchemy.schema.MetaData`
 
14
object, and the ``autoload=True`` flag. If the
 
15
:class:`~sqlalchemy.schema.MetaData` is not persistently bound, also add the
 
16
``autoload_with`` argument::
 
17
 
 
18
    >>> messages = Table('messages', meta, autoload=True, autoload_with=engine)
 
19
    >>> [c.name for c in messages.columns]
 
20
    ['message_id', 'message_name', 'date']
 
21
 
 
22
The above operation will use the given engine to query the database for
 
23
information about the ``messages`` table, and will then generate
 
24
:class:`~sqlalchemy.schema.Column`, :class:`~sqlalchemy.schema.ForeignKey`,
 
25
and other objects corresponding to this information as though the
 
26
:class:`~sqlalchemy.schema.Table` object were hand-constructed in Python.
 
27
 
 
28
When tables are reflected, if a given table references another one via foreign
 
29
key, a second :class:`~sqlalchemy.schema.Table` object is created within the
 
30
:class:`~sqlalchemy.schema.MetaData` object representing the connection.
 
31
Below, assume the table ``shopping_cart_items`` references a table named
 
32
``shopping_carts``. Reflecting the ``shopping_cart_items`` table has the
 
33
effect such that the ``shopping_carts`` table will also be loaded::
 
34
 
 
35
    >>> shopping_cart_items = Table('shopping_cart_items', meta, autoload=True, autoload_with=engine)
 
36
    >>> 'shopping_carts' in meta.tables:
 
37
    True
 
38
 
 
39
The :class:`~sqlalchemy.schema.MetaData` has an interesting "singleton-like"
 
40
behavior such that if you requested both tables individually,
 
41
:class:`~sqlalchemy.schema.MetaData` will ensure that exactly one
 
42
:class:`~sqlalchemy.schema.Table` object is created for each distinct table
 
43
name. The :class:`~sqlalchemy.schema.Table` constructor actually returns to
 
44
you the already-existing :class:`~sqlalchemy.schema.Table` object if one
 
45
already exists with the given name. Such as below, we can access the already
 
46
generated ``shopping_carts`` table just by naming it::
 
47
 
 
48
    shopping_carts = Table('shopping_carts', meta)
 
49
 
 
50
Of course, it's a good idea to use ``autoload=True`` with the above table
 
51
regardless. This is so that the table's attributes will be loaded if they have
 
52
not been already. The autoload operation only occurs for the table if it
 
53
hasn't already been loaded; once loaded, new calls to
 
54
:class:`~sqlalchemy.schema.Table` with the same name will not re-issue any
 
55
reflection queries.
 
56
 
 
57
Overriding Reflected Columns
 
58
-----------------------------
 
59
 
 
60
Individual columns can be overridden with explicit values when reflecting
 
61
tables; this is handy for specifying custom datatypes, constraints such as
 
62
primary keys that may not be configured within the database, etc.::
 
63
 
 
64
    >>> mytable = Table('mytable', meta,
 
65
    ... Column('id', Integer, primary_key=True),   # override reflected 'id' to have primary key
 
66
    ... Column('mydata', Unicode(50)),    # override reflected 'mydata' to be Unicode
 
67
    ... autoload=True)
 
68
 
 
69
Reflecting Views
 
70
-----------------
 
71
 
 
72
The reflection system can also reflect views. Basic usage is the same as that
 
73
of a table::
 
74
 
 
75
    my_view = Table("some_view", metadata, autoload=True)
 
76
 
 
77
Above, ``my_view`` is a :class:`~sqlalchemy.schema.Table` object with
 
78
:class:`~sqlalchemy.schema.Column` objects representing the names and types of
 
79
each column within the view "some_view".
 
80
 
 
81
Usually, it's desired to have at least a primary key constraint when
 
82
reflecting a view, if not foreign keys as well. View reflection doesn't
 
83
extrapolate these constraints.
 
84
 
 
85
Use the "override" technique for this, specifying explicitly those columns
 
86
which are part of the primary key or have foreign key constraints::
 
87
 
 
88
    my_view = Table("some_view", metadata,
 
89
                    Column("view_id", Integer, primary_key=True),
 
90
                    Column("related_thing", Integer, ForeignKey("othertable.thing_id")),
 
91
                    autoload=True
 
92
    )
 
93
 
 
94
Reflecting All Tables at Once
 
95
-----------------------------
 
96
 
 
97
The :class:`~sqlalchemy.schema.MetaData` object can also get a listing of
 
98
tables and reflect the full set. This is achieved by using the
 
99
:func:`~sqlalchemy.schema.MetaData.reflect` method. After calling it, all
 
100
located tables are present within the :class:`~sqlalchemy.schema.MetaData`
 
101
object's dictionary of tables::
 
102
 
 
103
    meta = MetaData()
 
104
    meta.reflect(bind=someengine)
 
105
    users_table = meta.tables['users']
 
106
    addresses_table = meta.tables['addresses']
 
107
 
 
108
``metadata.reflect()`` also provides a handy way to clear or delete all the rows in a database::
 
109
 
 
110
    meta = MetaData()
 
111
    meta.reflect(bind=someengine)
 
112
    for table in reversed(meta.sorted_tables):
 
113
        someengine.execute(table.delete())
 
114
 
 
115
Fine Grained Reflection with Inspector
 
116
--------------------------------------
 
117
 
 
118
A low level interface which provides a backend-agnostic system of loading
 
119
lists of schema, table, column, and constraint descriptions from a given
 
120
database is also available. This is known as the "Inspector"::
 
121
 
 
122
    from sqlalchemy import create_engine
 
123
    from sqlalchemy.engine import reflection
 
124
    engine = create_engine('...')
 
125
    insp = reflection.Inspector.from_engine(engine)
 
126
    print insp.get_table_names()
 
127
 
 
128
.. autoclass:: sqlalchemy.engine.reflection.Inspector
 
129
    :members:
 
130
    :undoc-members:
 
131
 
 
132
Limitations of Reflection
 
133
-------------------------
 
134
 
 
135
It's important to note that the reflection process recreates :class:`.Table`
 
136
metadata using only information which is represented in the relational database.
 
137
This process by definition cannot restore aspects of a schema that aren't
 
138
actually stored in the database.   State which is not available from reflection
 
139
includes but is not limited to:
 
140
 
 
141
* Client side defaults, either Python functions or SQL expressions defined using
 
142
  the ``default`` keyword of :class:`.Column` (note this is separate from ``server_default``,
 
143
  which specifically is what's available via reflection).
 
144
 
 
145
* Column information, e.g. data that might have been placed into the
 
146
  :attr:`.Column.info` dictionary
 
147
 
 
148
* The value of the ``.quote`` setting for :class:`.Column` or :class:`.Table`
 
149
 
 
150
* The assocation of a particular :class:`.Sequence` with a given :class:`.Column`
 
151
 
 
152
The relational database also in many cases reports on table metadata in a
 
153
different format than what was specified in SQLAlchemy.   The :class:`.Table`
 
154
objects returned from reflection cannot be always relied upon to produce the identical
 
155
DDL as the original Python-defined :class:`.Table` objects.   Areas where
 
156
this occurs includes server defaults, column-associated sequences and various
 
157
idosyncrasies regarding constraints and datatypes.   Server side defaults may
 
158
be returned with cast directives (typically Postgresql will include a ``::<type>``
 
159
cast) or different quoting patterns than originally specified.
 
160
 
 
161
Another category of limitation includes schema structures for which reflection
 
162
is only partially or not yet defined.  Recent improvements to reflection allow
 
163
things like views, indexes and foreign key options to be reflected.  As of this
 
164
writing, structures like CHECK constraints, table comments, and triggers are
 
165
not reflected.
 
166