diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2010-11-20 15:30:12 -0500 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2010-11-20 15:30:12 -0500 |
| commit | e187cc538d6fa9fe7fff8aa939dd787c07345f33 (patch) | |
| tree | eb3fbe19171ea9b7ce81fcdc52f9c50a9c2b0455 /lib | |
| parent | ccd4eeeb39b968641cdaee699ad2732ab903e793 (diff) | |
| parent | 08e5c35c2dd6ee3344bfe9077c6036a182baf5c8 (diff) | |
| download | sqlalchemy-e187cc538d6fa9fe7fff8aa939dd787c07345f33.tar.gz | |
- merge metadata/schema/declarative branch, [ticket:1893]
Diffstat (limited to 'lib')
| -rwxr-xr-x | lib/sqlalchemy/ext/declarative.py | 17 | ||||
| -rw-r--r-- | lib/sqlalchemy/schema.py | 33 |
2 files changed, 38 insertions, 12 deletions
diff --git a/lib/sqlalchemy/ext/declarative.py b/lib/sqlalchemy/ext/declarative.py index 8381e5ee1..40abfbb29 100755 --- a/lib/sqlalchemy/ext/declarative.py +++ b/lib/sqlalchemy/ext/declarative.py @@ -924,7 +924,7 @@ Mapped instances then make usage of """ -from sqlalchemy.schema import Table, Column, MetaData +from sqlalchemy.schema import Table, Column, MetaData, _get_table_key from sqlalchemy.orm import synonym as _orm_synonym, mapper,\ comparable_property, class_mapper from sqlalchemy.orm.interfaces import MapperProperty @@ -1261,8 +1261,8 @@ class DeclarativeMeta(type): class _GetColumns(object): def __init__(self, cls): self.cls = cls - def __getattr__(self, key): + def __getattr__(self, key): mapper = class_mapper(self.cls, compile=False) if mapper: if not mapper.has_property(key): @@ -1278,7 +1278,16 @@ class _GetColumns(object): " directly to a Column)." % key) return getattr(self.cls, key) - +class _GetTable(object): + def __init__(self, key, metadata): + self.key = key + self.metadata = metadata + + def __getattr__(self, key): + return self.metadata.tables[ + _get_table_key(key, self.key) + ] + def _deferred_relationship(cls, prop): def resolve_arg(arg): import sqlalchemy @@ -1288,6 +1297,8 @@ def _deferred_relationship(cls, prop): return _GetColumns(cls._decl_class_registry[key]) elif key in cls.metadata.tables: return cls.metadata.tables[key] + elif key in cls.metadata._schemas: + return _GetTable(key, cls.metadata) else: return sqlalchemy.__dict__[key] diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py index 980025676..50df8b9b6 100644 --- a/lib/sqlalchemy/schema.py +++ b/lib/sqlalchemy/schema.py @@ -207,12 +207,13 @@ class Table(SchemaItem, expression.TableClause): if mustexist: raise exc.InvalidRequestError( "Table '%s' not defined" % (key)) - metadata.tables[key] = table = object.__new__(cls) + table = object.__new__(cls) + metadata._add_table(name, schema, table) try: table._init(name, metadata, *args, **kw) return table except: - metadata.tables.pop(key) + metadata._remove_table(name, schema) raise def __init__(self, *args, **kw): @@ -387,7 +388,7 @@ class Table(SchemaItem, expression.TableClause): "on_" + event_name.replace('-', '_'), self) def _set_parent(self, metadata): - metadata.tables[_get_table_key(self.name, self.schema)] = self + metadata._add_table(self.name, self.schema, self) self.metadata = metadata def get_children(self, column_collections=True, @@ -1917,7 +1918,8 @@ class MetaData(SchemaItem): ``MetaData``. """ - self.tables = {} + self.tables = util.frozendict() + self._schemas = set() self.bind = bind self.metadata = self if reflect: @@ -1935,6 +1937,20 @@ class MetaData(SchemaItem): table_or_key = table_or_key.key return table_or_key in self.tables + def _add_table(self, name, schema, table): + key = _get_table_key(name, schema) + dict.__setitem__(self.tables, key, table) + if schema: + self._schemas.add(schema) + + def _remove_table(self, name, schema): + key = _get_table_key(name, schema) + dict.pop(self.tables, key, None) + if self._schemas: + self._schemas = set([t.schema + for t in self.tables.values() + if t.schema is not None]) + def __getstate__(self): return {'tables': self.tables} @@ -1969,15 +1985,14 @@ class MetaData(SchemaItem): def clear(self): """Clear all Table objects from this MetaData.""" - # TODO: why have clear()/remove() but not all - # other accesors/mutators for the tables dict ? - self.tables.clear() + dict.clear(self.tables) + self._schemas.clear() + def remove(self, table): """Remove the given Table object from this MetaData.""" - # TODO: scan all other tables and remove FK _column - del self.tables[table.key] + self._remove_table(table.name, table.schema) @property def sorted_tables(self): |
