summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/engine/reflection.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/engine/reflection.py')
-rw-r--r--lib/sqlalchemy/engine/reflection.py164
1 files changed, 115 insertions, 49 deletions
diff --git a/lib/sqlalchemy/engine/reflection.py b/lib/sqlalchemy/engine/reflection.py
index 50b3f774c..45f100518 100644
--- a/lib/sqlalchemy/engine/reflection.py
+++ b/lib/sqlalchemy/engine/reflection.py
@@ -1,5 +1,5 @@
# engine/reflection.py
-# Copyright (C) 2005-2013 the SQLAlchemy authors and contributors <see AUTHORS file>
+# Copyright (C) 2005-2014 the SQLAlchemy authors and contributors <see AUTHORS file>
#
# This module is part of SQLAlchemy and is released under
# the MIT License: http://www.opensource.org/licenses/mit-license.php
@@ -25,9 +25,9 @@ methods such as get_table_names, get_columns, etc.
"""
from .. import exc, sql
-from .. import schema as sa_schema
+from ..sql import schema as sa_schema
from .. import util
-from ..types import TypeEngine
+from ..sql.type_api import TypeEngine
from ..util import deprecated
from ..util import topological
from .. import inspection
@@ -161,7 +161,7 @@ class Inspector(object):
"""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:`.get_view_names`
+ Views are instead returned using the :meth:`.Inspector.get_view_names`
method.
@@ -169,7 +169,7 @@ class Inspector(object):
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``.
+ 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.
@@ -206,6 +206,13 @@ class Inspector(object):
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`.
+
"""
if hasattr(self.dialect, 'get_table_options'):
return self.dialect.get_table_options(
@@ -217,6 +224,8 @@ class Inspector(object):
"""Return all view names in `schema`.
:param schema: Optional, retrieve names from a non-default schema.
+ For special quoting, use :class:`.quoted_name`.
+
"""
return self.dialect.get_view_names(self.bind, schema,
@@ -226,6 +235,8 @@ class Inspector(object):
"""Return definition for `view_name`.
:param schema: Optional, retrieve names from a non-default schema.
+ For special quoting, use :class:`.quoted_name`.
+
"""
return self.dialect.get_view_definition(
@@ -251,6 +262,14 @@ class Inspector(object):
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`.
+
"""
col_defs = self.dialect.get_columns(self.bind, table_name, schema,
@@ -288,6 +307,13 @@ class Inspector(object):
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`.
+
"""
return self.dialect.get_pk_constraint(self.bind, table_name, schema,
info_cache=self.info_cache,
@@ -315,6 +341,13 @@ class Inspector(object):
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`.
+
"""
return self.dialect.get_foreign_keys(self.bind, table_name, schema,
@@ -336,6 +369,13 @@ class Inspector(object):
unique
boolean
+ :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 self.dialect.get_indexes(self.bind, table_name,
@@ -354,7 +394,14 @@ class Inspector(object):
column_names
list of column names in order
- .. versionadded:: 0.9.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`.
+
+ .. versionadded:: 0.8.4
"""
@@ -384,24 +431,25 @@ class Inspector(object):
"""
dialect = self.bind.dialect
- # table attributes we might need.
- reflection_options = dict(
- (k, table.kwargs.get(k)) for k in dialect.reflection_options if k in table.kwargs)
-
schema = table.schema
table_name = table.name
- # apply table options
- tbl_opts = self.get_table_options(table_name, schema, **table.kwargs)
- if tbl_opts:
- table.kwargs.update(tbl_opts)
+ # get table-level arguments that are specifically
+ # intended for reflection, e.g. oracle_resolve_synonyms.
+ # these are unconditionally passed to related Table
+ # objects
+ reflection_options = dict(
+ (k, table.dialect_kwargs.get(k))
+ for k in dialect.reflection_options
+ if k in table.dialect_kwargs
+ )
- # table.kwargs will need to be passed to each reflection method. Make
- # sure keywords are strings.
- tblkw = table.kwargs.copy()
- for (k, v) in list(tblkw.items()):
- del tblkw[k]
- tblkw[str(k)] = v
+ # reflect table options, like mysql_engine
+ tbl_opts = self.get_table_options(table_name, schema, **table.dialect_kwargs)
+ if tbl_opts:
+ # add additional kwargs to the Table if the dialect
+ # returned them
+ table._validate_dialect_kwargs(tbl_opts)
if util.py2k:
if isinstance(schema, str):
@@ -409,10 +457,13 @@ class Inspector(object):
if isinstance(table_name, str):
table_name = table_name.decode(dialect.encoding)
- # columns
found_table = False
- for col_d in self.get_columns(table_name, schema, **tblkw):
+ cols_by_orig_name = {}
+
+ for col_d in self.get_columns(table_name, schema, **table.dialect_kwargs):
found_table = True
+ orig_name = col_d['name']
+
table.dispatch.column_reflect(self, table, col_d)
name = col_d['name']
@@ -422,12 +473,12 @@ class Inspector(object):
continue
coltype = col_d['type']
- col_kw = {
- 'nullable': col_d['nullable'],
- }
- for k in ('autoincrement', 'quote', 'info', 'key'):
- if k in col_d:
- col_kw[k] = col_d[k]
+
+ col_kw = dict(
+ (k, col_d[k])
+ for k in ['nullable', 'autoincrement', 'quote', 'info', 'key']
+ if k in col_d
+ )
colargs = []
if col_d.get('default') is not None:
@@ -441,7 +492,7 @@ class Inspector(object):
)
if 'sequence' in col_d:
- # TODO: mssql, maxdb and sybase are using this.
+ # TODO: mssql and sybase are using this.
seq = col_d['sequence']
sequence = sa_schema.Sequence(seq['name'], 1, 1)
if 'start' in seq:
@@ -450,37 +501,41 @@ class Inspector(object):
sequence.increment = seq['increment']
colargs.append(sequence)
- col = sa_schema.Column(name, coltype, *colargs, **col_kw)
+ cols_by_orig_name[orig_name] = col = \
+ sa_schema.Column(name, coltype, *colargs, **col_kw)
+
+ if col.key in table.primary_key:
+ col.primary_key = True
table.append_column(col)
if not found_table:
raise exc.NoSuchTableError(table.name)
- # Primary keys
- pk_cons = self.get_pk_constraint(table_name, schema, **tblkw)
+ pk_cons = self.get_pk_constraint(table_name, schema, **table.dialect_kwargs)
if pk_cons:
pk_cols = [
- table.c[pk]
+ cols_by_orig_name[pk]
for pk in pk_cons['constrained_columns']
- if pk in table.c and pk not in exclude_columns
- ]
- pk_cols += [
- pk
- for pk in table.primary_key
- if pk.key in exclude_columns
+ if pk in cols_by_orig_name and pk not in exclude_columns
]
- primary_key_constraint = sa_schema.PrimaryKeyConstraint(
- name=pk_cons.get('name'),
- *pk_cols
- )
- table.append_constraint(primary_key_constraint)
+ # update pk constraint name
+ table.primary_key.name = pk_cons.get('name')
+
+ # tell the PKConstraint to re-initialize
+ # it's column collection
+ table.primary_key._reload(pk_cols)
- # Foreign keys
- fkeys = self.get_foreign_keys(table_name, schema, **tblkw)
+ fkeys = self.get_foreign_keys(table_name, schema, **table.dialect_kwargs)
for fkey_d in fkeys:
conname = fkey_d['name']
- constrained_columns = fkey_d['constrained_columns']
+ # look for columns by orig name in cols_by_orig_name,
+ # but support columns that are in-Python only as fallback
+ constrained_columns = [
+ cols_by_orig_name[c].key
+ if c in cols_by_orig_name else c
+ for c in fkey_d['constrained_columns']
+ ]
if exclude_columns and set(constrained_columns).intersection(
exclude_columns):
continue
@@ -504,9 +559,14 @@ class Inspector(object):
)
for column in referred_columns:
refspec.append(".".join([referred_table, column]))
+ if 'options' in fkey_d:
+ options = fkey_d['options']
+ else:
+ options = {}
table.append_constraint(
sa_schema.ForeignKeyConstraint(constrained_columns, refspec,
- conname, link_to_name=True))
+ conname, link_to_name=True,
+ **options))
# Indexes
indexes = self.get_indexes(table_name, schema)
for index_d in indexes:
@@ -520,5 +580,11 @@ class Inspector(object):
"Omitting %s KEY for (%s), key covers omitted columns." %
(flavor, ', '.join(columns)))
continue
- sa_schema.Index(name, *[table.columns[c] for c in columns],
+ # look for columns by orig name in cols_by_orig_name,
+ # but support columns that are in-Python only as fallback
+ sa_schema.Index(name, *[
+ cols_by_orig_name[c] if c in cols_by_orig_name
+ else table.c[c]
+ for c in columns
+ ],
**dict(unique=unique))