From: Mike Bayer Date: Sat, 4 Feb 2006 17:24:12 +0000 (+0000) Subject: added ISchema object to engine/information_schema, provides somewhat generic informat... X-Git-Tag: rel_0_1_0~67 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=385cf6e7b67dc2a51672bc8272da44e0a8cad1b1;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git added ISchema object to engine/information_schema, provides somewhat generic information_schema access for db's that support it, i.e. postgres, mysql 5 --- diff --git a/lib/sqlalchemy/databases/information_schema.py b/lib/sqlalchemy/databases/information_schema.py index dae3af2c69..c0503c25ce 100644 --- a/lib/sqlalchemy/databases/information_schema.py +++ b/lib/sqlalchemy/databases/information_schema.py @@ -7,6 +7,20 @@ from sqlalchemy import * from sqlalchemy.ansisql import * generic_engine = ansisql.engine() + +gen_schemata = schema.Table("schemata", generic_engine, + Column("catalog_name", String), + Column("schema_name", String), + Column("schema_owner", String), + schema="information_schema") + +gen_tables = schema.Table("tables", generic_engine, + Column("table_catalog", String), + Column("table_schema", String), + Column("table_name", String), + Column("table_type", String), + schema="information_schema") + gen_columns = schema.Table("columns", generic_engine, Column("table_schema", String), Column("table_name", String), @@ -40,6 +54,25 @@ gen_key_constraints = schema.Table("key_column_usage", generic_engine, Column("constraint_name", String), schema="information_schema") +class ISchema(object): + def __init__(self, engine): + self.engine = engine + self.cache = {} + def __getattr__(self, name): + if name not in self.cache: + # This is a bit of a hack. + # It would probably be better to have a dict + # with just the information_schema tables at + # the module level, so as to avoid returning + # unrelated objects that happen to be named + # 'gen_*' + try: + gen_tbl = globals()['gen_'+name] + except KeyError: + raise AttributeError('information_schema table %s not found' % name) + self.cache[name] = gen_tbl.toengine(self.engine) + return self.cache[name] + def reflecttable(engine, table, ischema_names, use_mysql=False): columns = gen_columns.toengine(engine) diff --git a/lib/sqlalchemy/engine.py b/lib/sqlalchemy/engine.py index 5952947412..d99e5eb6ca 100644 --- a/lib/sqlalchemy/engine.py +++ b/lib/sqlalchemy/engine.py @@ -178,12 +178,24 @@ class SQLEngine(schema.SchemaEngine): self.echo_uow = echo_uow self.context = util.ThreadLocal(raiseerror=False) self.tables = {} + self._ischema = None self._figure_paramstyle() if logger is None: self.logger = sys.stdout else: self.logger = logger + def _get_ischema(self): + # We use a property for ischema so that the accessor + # creation only happens as needed, since otherwise we + # have a circularity problem with the generic + # ansisql.engine() + if self._ischema is None: + import sqlalchemy.databases.information_schema as ischema + self._ischema = ischema.ISchema(self) + return self._ischema + ischema = property(_get_ischema, doc="""returns an ISchema object for this engine, which allows access to information_schema tables (if supported)""") + def hash_key(self): return "%s(%s)" % (self.__class__.__name__, repr(self.connect_args()))