From 610e8be4e72e2938aeb96f689a371ee1b93c813d Mon Sep 17 00:00:00 2001 From: Lele Gaifax Date: Wed, 15 Apr 2009 09:30:10 +0000 Subject: [PATCH] Whitespace normalization, adjust some docstrings to reST/Sphinx conventions --- lib/sqlalchemy/engine/base.py | 292 ++++++++++++++------------- lib/sqlalchemy/engine/ddl.py | 30 ++- lib/sqlalchemy/engine/default.py | 46 +++-- lib/sqlalchemy/engine/reflection.py | 60 +++--- lib/sqlalchemy/engine/strategies.py | 6 +- lib/sqlalchemy/engine/threadlocal.py | 4 +- lib/sqlalchemy/engine/url.py | 34 ++-- 7 files changed, 246 insertions(+), 226 deletions(-) diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index a884221bd3..e2df98b63f 100644 --- a/lib/sqlalchemy/engine/base.py +++ b/lib/sqlalchemy/engine/base.py @@ -10,12 +10,14 @@ Defines the basic components used to interface DB-API modules with higher-level statement-construction, connection-management, execution and result contexts. - """ -__all__ = ['BufferedColumnResultProxy', 'BufferedColumnRow', 'BufferedRowResultProxy', 'Compiled', 'Connectable', - 'Connection', 'DefaultRunner', 'Dialect', 'Engine', 'ExecutionContext', 'NestedTransaction', 'ResultProxy', - 'RootTransaction', 'RowProxy', 'SchemaIterator', 'StringIO', 'Transaction', 'TwoPhaseTransaction', 'connection_memoize'] +__all__ = [ + 'BufferedColumnResultProxy', 'BufferedColumnRow', 'BufferedRowResultProxy', + 'Compiled', 'Connectable', 'Connection', 'DefaultRunner', 'Dialect', 'Engine', + 'ExecutionContext', 'NestedTransaction', 'ResultProxy', 'RootTransaction', + 'RowProxy', 'SchemaIterator', 'StringIO', 'Transaction', 'TwoPhaseTransaction', + 'connection_memoize'] import inspect, StringIO, sys from sqlalchemy import exc, schema, util, types, log @@ -32,14 +34,14 @@ class Dialect(object): ExecutionContext, Compiled, DefaultGenerator, and TypeEngine. All Dialects implement the following attributes: - + name identifying name for the dialect from a DBAPI-neutral point of view (i.e. 'sqlite') - + driver - identitfying name for the dialect's DBAPI - + identitfying name for the dialect's DBAPI + positional True if the paramstyle for this Dialect is positional. @@ -60,16 +62,14 @@ class Dialect(object): defaults. statement_compiler - a :class:`~Compiled` class used to compile SQL - statements + a :class:`~Compiled` class used to compile SQL statements ddl_compiler - a :class:`~Compiled` class used to compile DDL - statements + a :class:`~Compiled` class used to compile DDL statements server_version_info a tuple containing a version number for the DB backend in use. - This value is only available for supporting dialects, and only for + This value is only available for supporting dialects, and only for a dialect that's been associated with a connection pool via create_engine() or otherwise had its ``initialize()`` method called with a conneciton. @@ -88,22 +88,26 @@ class Dialect(object): The maximum length of identifier names. supports_unicode_statements - Indicate whether the DB-API can receive SQL statements as Python unicode strings + Indicate whether the DB-API can receive SQL statements as Python + unicode strings supports_unicode_binds - Indicate whether the DB-API can receive string bind parameters as Python unicode strings + Indicate whether the DB-API can receive string bind parameters + as Python unicode strings supports_sane_rowcount - Indicate whether the dialect properly implements rowcount for ``UPDATE`` and ``DELETE`` statements. + Indicate whether the dialect properly implements rowcount for + ``UPDATE`` and ``DELETE`` statements. supports_sane_multi_rowcount - Indicate whether the dialect properly implements rowcount for ``UPDATE`` and ``DELETE`` statements - when executed via executemany. + Indicate whether the dialect properly implements rowcount for + ``UPDATE`` and ``DELETE`` statements when executed via + executemany. preexecute_pk_sequences - Indicate if the dialect should pre-execute sequences on primary key - columns during an INSERT, if it's desired that the new row's primary key - be available after execution. + Indicate if the dialect should pre-execute sequences on primary + key columns during an INSERT, if it's desired that the new row's + primary key be available after execution. supports_pk_autoincrement Indicates if the dialect should allow the database to passively assign @@ -111,22 +115,23 @@ class Dialect(object): dbapi_type_map A mapping of DB-API type objects present in this Dialect's - DB-API implmentation mapped to TypeEngine implementations used + DB-API implementation mapped to TypeEngine implementations used by the dialect. This is used to apply types to result sets based on the DB-API types present in cursor.description; it only takes effect for result sets against textual statements where no explicit typemap was present. - + colspecs - A dictionary of TypeEngine classes from sqlalchemy.types mapped to subclasses - that are specific to the dialect class. This dictionary is class-level only - and is not accessed from the dialect instance itself. - + A dictionary of TypeEngine classes from sqlalchemy.types mapped + to subclasses that are specific to the dialect class. This + dictionary is class-level only and is not accessed from the + dialect instance itself. + supports_default_values - Indicates if the construct ``INSERT INTO tablename DEFAULT VALUES`` is supported - + Indicates if the construct ``INSERT INTO tablename DEFAULT + VALUES`` is supported """ def create_connect_args(self, url): @@ -139,7 +144,6 @@ class Dialect(object): raise NotImplementedError() - @classmethod def type_descriptor(cls, typeobj): """Transform a generic type to a dialect-specific type. @@ -147,22 +151,20 @@ class Dialect(object): Dialect classes will usually use the :func:`~sqlalchemy.types.adapt_type` method in the types module to make this job easy. - + The returned result is cached *per dialect class* so can contain no dialect-instance state. - """ raise NotImplementedError() - def initialize(self, connection): """Called during strategized creation of the dialect with a connection. - + Allows dialects to configure options based on server version info or other properties. - """ + pass def reflecttable(self, connection, table, include_columns=None): @@ -180,9 +182,9 @@ class Dialect(object): def get_columns(self, connection, table_name, schema=None, **kw): """Return information about columns in `table_name`. - Given a [sqlalchemy.engine#Connection], a string `table_name`, and an - optional string `schema`, return column information as a list of - dictionaries with these keys: + Given a :class:`~sqlalchemy.engine.Connection`, a string + `table_name`, and an optional string `schema`, return column + information as a list of dictionaries with these keys: name the column's name @@ -205,10 +207,9 @@ class Dialect(object): def get_primary_keys(self, connection, table_name, schema=None, **kw): """Return information about primary keys in `table_name`. - Given a [sqlalchemy.engine#Connection], a string `table_name`, and an - optional string `schema`, return primary key information as a list of - column names. - + Given a :class:`~sqlalchemy.engine.Connection`, a string + `table_name`, and an optional string `schema`, return primary + key information as a list of column names. """ raise NotImplementedError() @@ -216,9 +217,9 @@ class Dialect(object): def get_foreign_keys(self, connection, table_name, schema=None, **kw): """Return information about foreign_keys in `table_name`. - Given a [sqlalchemy.engine#Connection], a string `table_name`, and an - optional string `schema`, return foreign key information as a list of - dicts with these keys: + Given a :class:`~sqlalchemy.engine.Connection`, a string + `table_name`, and an optional string `schema`, return foreign + key information as a list of dicts with these keys: name the constraint's name @@ -249,7 +250,6 @@ class Dialect(object): schema: Optional, retrieve names from a non-default schema. - """ raise NotImplementedError() @@ -257,9 +257,9 @@ class Dialect(object): def get_view_definition(self, connection, view_name, schema=None, **kw): """Return view definition. - Given a [sqlalchemy.engine#Connection], a string `view_name`, and an - optional string `schema`, return the view definition. - + Given a :class:`~sqlalchemy.engine.Connection`, a string + `view_name`, and an optional string `schema`, return the view + definition. """ raise NotImplementedError() @@ -267,9 +267,9 @@ class Dialect(object): def get_indexes(self, connection, table_name, schema=None, **kw): """Return information about indexes in `table_name`. - Given a [sqlalchemy.engine#Connection], a string `table_name` and an - optional string `schema`, return index information as a list of - dictionaries with these keys: + Given a :class:`~sqlalchemy.engine.Connection`, a string + `table_name` and an optional string `schema`, return index + information as a list of dictionaries with these keys: name the index's name @@ -279,7 +279,6 @@ class Dialect(object): unique boolean - """ raise NotImplementedError() @@ -397,7 +396,7 @@ class Dialect(object): class ExecutionContext(object): """A messenger object for a Dialect that corresponds to a single execution. - ExecutionContext should have these datamembers: + ExecutionContext should have these data members: connection Connection object which can be freely used by default value @@ -439,13 +438,12 @@ class ExecutionContext(object): True if the statement is an UPDATE. should_autocommit - True if the statement is a "committable" statement + True if the statement is a "committable" statement. postfetch_cols - a list of Column objects for which a server-side default - or inline SQL expression value was fired off. applies to inserts and updates. - - + a list of Column objects for which a server-side default or + inline SQL expression value was fired off. Applies to inserts + and updates. """ def create_cursor(self): @@ -488,9 +486,9 @@ class ExecutionContext(object): def handle_dbapi_exception(self, e): """Receive a DBAPI exception which occured upon execute, result fetch, etc.""" - + raise NotImplementedError() - + def should_autocommit_text(self, statement): """Parse the given textual statement and return True if it refers to a "committable" statement""" @@ -542,22 +540,18 @@ class Compiled(object): ``Compiled`` object be dependent on the actual values of those bind parameters, even though it may reference those values as defaults. - """ def __init__(self, dialect, statement, bind=None): """Construct a new ``Compiled`` object. - dialect - ``Dialect`` to compile against. + :param dialect: ``Dialect`` to compile against. - statement - ``ClauseElement`` to be compiled. + :param statement: ``ClauseElement`` to be compiled. - bind - Optional Engine or Connection to compile this statement against. - + :param bind: Optional Engine or Connection to compile this statement against. """ + self.dialect = dialect self.statement = statement self.bind = bind @@ -584,11 +578,11 @@ class Compiled(object): def construct_params(self, params=None): """Return the bind params for this compiled object. - `params` is a dict of string/object pairs whos - values will override bind values compiled in - to the statement. - + :param params: a dict of string/object pairs whos values will + override bind values compiled in to the + statement. """ + raise NotImplementedError() def execute(self, *multiparams, **params): @@ -604,25 +598,25 @@ class Compiled(object): return self.execute(*multiparams, **params).scalar() + class TypeCompiler(object): """Produces DDL specification for TypeEngine objects.""" - + def __init__(self, dialect): self.dialect = dialect - + def process(self, type_): return type_._compiler_dispatch(self) - + class Connectable(object): """Interface for an object which supports execution of SQL constructs. - + The two implementations of ``Connectable`` are :class:`Connection` and :class:`Engine`. - + Connectable must also implement the 'dialect' member which references a :class:`Dialect` instance. - """ def contextual_connect(self): @@ -646,6 +640,7 @@ class Connectable(object): def _execute_clauseelement(self, elem, multiparams=None, params=None): raise NotImplementedError() + class Connection(Connectable): """Provides high-level functionality for a wrapped DB-API connection. @@ -657,7 +652,6 @@ class Connection(Connectable): .. index:: single: thread safety; Connection - """ def __init__(self, engine, connection=None, close_with_result=False, @@ -667,7 +661,6 @@ class Connection(Connectable): Connection objects are typically constructed by an :class:`~sqlalchemy.engine.Engine`, see the ``connect()`` and ``contextual_connect()`` methods of Engine. - """ self.engine = engine @@ -677,7 +670,7 @@ class Connection(Connectable): self.__savepoint_seq = 0 self.__branch = _branch self.__invalid = False - + def _branch(self): """Return a new Connection which references this Connection's engine and connection; but does not have close_with_result enabled, @@ -685,8 +678,8 @@ class Connection(Connectable): This is used to execute "sub" statements within a single execution, usually an INSERT statement. - """ + return self.engine.Connection(self.engine, self.__connection, _branch=True) @property @@ -697,13 +690,13 @@ class Connection(Connectable): @property def closed(self): - """return True if this connection is closed.""" + """Return True if this connection is closed.""" return not self.__invalid and '_Connection__connection' not in self.__dict__ @property def invalidated(self): - """return True if this connection was invalidated.""" + """Return True if this connection was invalidated.""" return self.__invalid @@ -726,13 +719,14 @@ class Connection(Connectable): def should_close_with_result(self): """Indicates if this Connection should be closed when a corresponding ResultProxy is closed; this is essentially an auto-release mode. - """ + return self.__close_with_result @property def info(self): """A collection of per-DB-API connection instance properties.""" + return self.connection.info def connect(self): @@ -741,8 +735,8 @@ class Connection(Connectable): This ``Connectable`` interface method returns self, allowing Connections to be used interchangably with Engines in most situations that require a bind. - """ + return self def contextual_connect(self, **kwargs): @@ -751,8 +745,8 @@ class Connection(Connectable): This ``Connectable`` interface method returns self, allowing Connections to be used interchangably with Engines in most situations that require a bind. - """ + return self def invalidate(self, exception=None): @@ -770,8 +764,8 @@ class Connection(Connectable): rolled back before a reconnect on this Connection can proceed. This is to prevent applications from accidentally continuing their transactional operations in a non-transactional state. - """ + if self.closed: raise exc.InvalidRequestError("This Connection is closed") @@ -794,8 +788,8 @@ class Connection(Connectable): :class:`~sqlalchemy.interfaces.PoolListener` for a mechanism to modify connection state when connections leave and return to their connection pool. - """ + self.__connection.detach() def begin(self): @@ -806,8 +800,8 @@ class Connection(Connectable): outermost transaction may ``commit``. Calls to ``commit`` on inner transactions are ignored. Any transaction in the hierarchy may ``rollback``, however. - """ + if self.__transaction is None: self.__transaction = RootTransaction(self) else: @@ -833,9 +827,8 @@ class Connection(Connectable): def begin_twophase(self, xid=None): """Begin a two-phase or XA transaction and return a Transaction handle. - xid - the two phase transaction id. If not supplied, a random id - will be generated. + :param xid: the two phase transaction id. If not supplied, a random id + will be generated. """ if self.__transaction is not None: @@ -966,11 +959,12 @@ class Connection(Connectable): raise exc.InvalidRequestError("Unexecutable object type: " + str(type(object))) def __distill_params(self, multiparams, params): - """given arguments from the calling form *multiparams, **params, return a list + """Given arguments from the calling form *multiparams, **params, return a list of bind parameter structures, usually a list of dictionaries. - in the case of 'raw' execution which accepts positional parameters, - it may be a list of tuples or lists.""" + In the case of 'raw' execution which accepts positional parameters, + it may be a list of tuples or lists. + """ if not multiparams: if params: @@ -1002,7 +996,7 @@ class Connection(Connectable): def _execute_ddl(self, ddl, params, multiparams): context = self.__create_execution_context( - compiled_ddl=ddl.compile(dialect=self.dialect), + compiled_ddl=ddl.compile(dialect=self.dialect), parameters=None ) return self.__execute_context(context) @@ -1015,7 +1009,7 @@ class Connection(Connectable): keys = [] context = self.__create_execution_context( - compiled_sql=elem.compile(dialect=self.dialect, column_keys=keys, inline=len(params) > 1), + compiled_sql=elem.compile(dialect=self.dialect, column_keys=keys, inline=len(params) > 1), parameters=params ) return self.__execute_context(context) @@ -1024,7 +1018,7 @@ class Connection(Connectable): """Execute a sql.Compiled object.""" context = self.__create_execution_context( - compiled_sql=compiled, + compiled_sql=compiled, parameters=self.__distill_params(multiparams, params) ) return self.__execute_context(context) @@ -1033,7 +1027,7 @@ class Connection(Connectable): parameters = self.__distill_params(multiparams, params) context = self.__create_execution_context(statement=statement, parameters=parameters) return self.__execute_context(context) - + def __execute_context(self, context): if context.compiled: context.pre_exec() @@ -1046,7 +1040,7 @@ class Connection(Connectable): if context.should_autocommit and not self.in_transaction(): self._commit_impl() return context.get_result_proxy() - + def _handle_dbapi_exception(self, e, statement, parameters, cursor, context): if getattr(self, '_reentrant_error', False): raise exc.DBAPIError.instance(statement, parameters, e), None, sys.exc_info()[2] @@ -1054,10 +1048,10 @@ class Connection(Connectable): try: if not isinstance(e, self.dialect.dbapi.Error): return - + if context: context.handle_dbapi_exception(e) - + is_disconnect = self.dialect.is_disconnect(e) if is_disconnect: self.invalidate(e) @@ -1131,6 +1125,7 @@ class Connection(Connectable): def run_callable(self, callable_): return callable_(self) + class Transaction(object): """Represent a Transaction in progress. @@ -1138,14 +1133,13 @@ class Transaction(object): .. index:: single: thread safety; Transaction - """ def __init__(self, connection, parent): self.connection = connection self._parent = parent or self self.is_active = True - + def close(self): """Close this transaction. @@ -1156,6 +1150,7 @@ class Transaction(object): This is used to cancel a Transaction without affecting the scope of an enclosing transaction. """ + if not self._parent.is_active: return if self._parent is self: @@ -1188,6 +1183,7 @@ class Transaction(object): else: self.rollback() + class RootTransaction(Transaction): def __init__(self, connection): super(RootTransaction, self).__init__(connection, None) @@ -1199,6 +1195,7 @@ class RootTransaction(Transaction): def _do_commit(self): self.connection._commit_impl() + class NestedTransaction(Transaction): def __init__(self, connection, parent): super(NestedTransaction, self).__init__(connection, parent) @@ -1210,6 +1207,7 @@ class NestedTransaction(Transaction): def _do_commit(self): self.connection._release_savepoint_impl(self._savepoint, self._parent) + class TwoPhaseTransaction(Transaction): def __init__(self, connection, xid): super(TwoPhaseTransaction, self).__init__(connection, None) @@ -1229,9 +1227,10 @@ class TwoPhaseTransaction(Transaction): def commit(self): self.connection._commit_twophase_impl(self.xid, self._is_prepared) + class Engine(Connectable): """ - Connects a :class:`~sqlalchemy.pool.Pool` and :class:`~sqlalchemy.engine.base.Dialect` + Connects a :class:`~sqlalchemy.pool.Pool` and :class:`~sqlalchemy.engine.base.Dialect` together to provide a source of database connectivity and behavior. """ @@ -1251,7 +1250,7 @@ class Engine(Connectable): @property def name(self): "String name of the :class:`~sqlalchemy.engine.Dialect` in use by this ``Engine``." - + return self.dialect.name @property @@ -1378,12 +1377,10 @@ class Engine(Connectable): def table_names(self, schema=None, connection=None): """Return a list of all table names available in the database. - schema: - Optional, retrieve names from a non-default schema. + :param schema: Optional, retrieve names from a non-default schema. - connection: - Optional, use a specified connection. Default is the - ``contextual_connect`` for this ``Engine``. + :param connection: Optional, use a specified connection. Default is the + ``contextual_connect`` for this ``Engine``. """ if connection is None: @@ -1422,22 +1419,24 @@ class Engine(Connectable): return self.pool.unique_connection() + def _proxy_connection_cls(cls, proxy): class ProxyConnection(cls): def execute(self, object, *multiparams, **params): return proxy.execute(self, super(ProxyConnection, self).execute, object, *multiparams, **params) - + def _execute_clauseelement(self, elem, multiparams=None, params=None): return proxy.execute(self, super(ProxyConnection, self).execute, elem, *(multiparams or []), **(params or {})) - + def _cursor_execute(self, cursor, statement, parameters, context=None): return proxy.cursor_execute(super(ProxyConnection, self)._cursor_execute, cursor, statement, parameters, context, False) - + def _cursor_executemany(self, cursor, statement, parameters, context=None): return proxy.cursor_execute(super(ProxyConnection, self)._cursor_executemany, cursor, statement, parameters, context, True) return ProxyConnection + class RowProxy(object): """Proxy a single cursor row for a parent ResultProxy. @@ -1449,7 +1448,7 @@ class RowProxy(object): """ __slots__ = ['__parent', '__row'] - + def __init__(self, parent, row): """RowProxy objects are constructed by ResultProxy objects.""" @@ -1474,7 +1473,7 @@ class RowProxy(object): yield self.__parent._get_col(self.__row, i) __hash__ = None - + def __eq__(self, other): return ((other is self) or (other == tuple(self.__parent._get_col(self.__row, key) @@ -1509,18 +1508,19 @@ class RowProxy(object): """Return the list of keys as strings represented by this RowProxy.""" return self.__parent.keys - + def iterkeys(self): return iter(self.__parent.keys) - + def values(self): """Return the values represented by this RowProxy as a list.""" return list(self) - + def itervalues(self): return iter(self) + class BufferedColumnRow(RowProxy): def __init__(self, parent, row): row = [ResultProxy._get_col(parent, row, i) for i in xrange(len(row))] @@ -1560,7 +1560,7 @@ class ResultProxy(object): self.connection = context.root_connection self._echo = context.engine._should_log_info self._init_metadata() - + @property def rowcount(self): if self._rowcount is None: @@ -1584,7 +1584,7 @@ class ResultProxy(object): self._rowcount = self.context.get_rowcount() self.close() return - + self._rowcount = None self._props = util.populate_column_dict(None) self._props.creator = self.__key_fallback() @@ -1597,7 +1597,7 @@ class ResultProxy(object): if self.dialect.description_encoding: colname = colname.decode(self.dialect.description_encoding) - + if '.' in colname: # sqlite will in some circumstances prepend table name to colnames, so strip origname = colname @@ -1632,11 +1632,11 @@ class ResultProxy(object): if self._echo: self.context.engine.logger.debug( "Col " + repr(tuple(x[0] for x in metadata))) - + def __key_fallback(self): # create a closure without 'self' to avoid circular references props = self._props - + def fallback(key): if isinstance(key, basestring): key = key.lower() @@ -1663,7 +1663,7 @@ class ResultProxy(object): def close(self): """Close this ResultProxy. - + Closes the underlying DBAPI cursor corresponding to the execution. If this ResultProxy was generated from an implicit execution, @@ -1671,11 +1671,11 @@ class ResultProxy(object): underlying DBAPI connection to the connection pool.) This method is called automatically when: - - * all result rows are exhausted using the fetchXXX() methods. - * cursor.description is None. - + + * all result rows are exhausted using the fetchXXX() methods. + * cursor.description is None. """ + if not self.closed: self.closed = True self.cursor.close() @@ -1703,48 +1703,48 @@ class ResultProxy(object): """Return ``last_inserted_ids()`` from the underlying ExecutionContext. See ExecutionContext for details. - """ + return self.context.last_inserted_ids() def last_updated_params(self): """Return ``last_updated_params()`` from the underlying ExecutionContext. See ExecutionContext for details. - """ + return self.context.last_updated_params() def last_inserted_params(self): """Return ``last_inserted_params()`` from the underlying ExecutionContext. See ExecutionContext for details. - """ + return self.context.last_inserted_params() def lastrow_has_defaults(self): """Return ``lastrow_has_defaults()`` from the underlying ExecutionContext. See ExecutionContext for details. - """ + return self.context.lastrow_has_defaults() def postfetch_cols(self): """Return ``postfetch_cols()`` from the underlying ExecutionContext. See ExecutionContext for details. - """ + return self.context.postfetch_cols - + def prefetch_cols(self): return self.context.prefetch_cols - + def supports_sane_rowcount(self): """Return ``supports_sane_rowcount`` from the dialect.""" - + return self.dialect.supports_sane_rowcount def supports_sane_multi_rowcount(self): @@ -1805,6 +1805,7 @@ class ResultProxy(object): def fetchone(self): """Fetch one row, just like DB-API ``cursor.fetchone()``.""" + try: row = self._fetchone_impl() if row is not None: @@ -1818,12 +1819,13 @@ class ResultProxy(object): def scalar(self): """Fetch the first column of the first row, and close the result set.""" + try: row = self._fetchone_impl() except Exception, e: self.connection._handle_dbapi_exception(e, None, None, self.cursor, self.context) raise - + try: if row is not None: return self._process_row(self, row)[0] @@ -1832,6 +1834,7 @@ class ResultProxy(object): finally: self.close() + class BufferedRowResultProxy(ResultProxy): """A ResultProxy with row buffering behavior. @@ -1845,7 +1848,6 @@ class BufferedRowResultProxy(ResultProxy): The pre-fetching behavior fetches only one row initially, and then grows its buffer size by a fixed amount with each successive need for additional rows up to a size of 100. - """ def _init_metadata(self): @@ -1890,6 +1892,7 @@ class BufferedRowResultProxy(ResultProxy): def _fetchall_impl(self): return self.__rowbuffer + list(self.cursor.fetchall()) + class BufferedColumnResultProxy(ResultProxy): """A ResultProxy with column buffering behavior. @@ -1900,7 +1903,6 @@ class BufferedColumnResultProxy(ResultProxy): of scope unless explicitly fetched. Currently this includes just cx_Oracle LOB objects, but this behavior is known to exist in other DB-APIs as well (Pygresql, currently unsupported). - """ _process_row = BufferedColumnRow @@ -1938,6 +1940,7 @@ class BufferedColumnResultProxy(ResultProxy): l.append(row) return l + class DefaultRunner(schema.SchemaVisitor): """A visitor which accepts ColumnDefault objects, produces the dialect-specific SQL corresponding to their execution, and @@ -1946,7 +1949,6 @@ class DefaultRunner(schema.SchemaVisitor): DefaultRunners are used internally by Engines and Dialects. Specific database modules should provide their own subclasses of DefaultRunner to allow database-specific behavior. - """ def __init__(self, context): @@ -1979,7 +1981,7 @@ class DefaultRunner(schema.SchemaVisitor): def execute_string(self, stmt, params=None): """execute a string statement, using the raw cursor, and return a scalar result.""" - + conn = self.context._connection if isinstance(stmt, unicode) and not self.dialect.supports_unicode_statements: stmt = stmt.encode(self.dialect.encoding) @@ -2008,8 +2010,8 @@ def connection_memoize(key): Only applicable to functions which take no arguments other than a connection. The memo will be stored in ``connection.info[key]``. - """ + @util.decorator def decorated(fn, self, connection): connection = connection.connect() diff --git a/lib/sqlalchemy/engine/ddl.py b/lib/sqlalchemy/engine/ddl.py index 2fc09a20b8..ad040201d9 100644 --- a/lib/sqlalchemy/engine/ddl.py +++ b/lib/sqlalchemy/engine/ddl.py @@ -1,15 +1,22 @@ -"""routines to handle CREATE/DROP workflow.""" +# engine/ddl.py +# Copyright (C) 2009 Michael Bayer mike_mp@zzzcomputing.com +# +# This module is part of SQLAlchemy and is released under +# the MIT License: http://www.opensource.org/licenses/mit-license.php -### TOOD: CREATE TABLE and DROP TABLE have been moved out so far. +"""Routines to handle CREATE/DROP workflow.""" + +### TODO: CREATE TABLE and DROP TABLE have been moved out so far. ### Index, ForeignKey, etc. still need to move. from sqlalchemy import engine, schema from sqlalchemy.sql import util as sql_util + class DDLBase(schema.SchemaVisitor): def __init__(self, connection): self.connection = connection - + def find_alterables(self, tables): alterables = [] class FindAlterables(schema.SchemaVisitor): @@ -68,14 +75,16 @@ class SchemaGenerator(DDLBase): def visit_sequence(self, sequence): if self.dialect.supports_sequences: - if \ - (not self.dialect.sequences_optional or not sequence.optional) and \ - (not self.checkfirst or not self.dialect.has_sequence(self.connection, sequence.name)): + if ((not self.dialect.sequences_optional or + not sequence.optional) and + (not self.checkfirst or + not self.dialect.has_sequence(self.connection, sequence.name))): self.connection.execute(schema.CreateSequence(sequence)) def visit_index(self, index): self.connection.execute(schema.CreateIndex(index)) + class SchemaDropper(DDLBase): def __init__(self, dialect, connection, checkfirst=False, tables=None, **kwargs): super(SchemaDropper, self).__init__(connection, **kwargs) @@ -112,7 +121,7 @@ class SchemaDropper(DDLBase): for column in table.columns: if column.default is not None: self.traverse_single(column.default) - + self.connection.execute(schema.DropTable(table)) for listener in table.ddl_listeners['after-drop']: @@ -120,7 +129,8 @@ class SchemaDropper(DDLBase): def visit_sequence(self, sequence): if self.dialect.supports_sequences: - if \ - (not self.dialect.sequences_optional or not sequence.optional) and \ - (not self.checkfirst or self.dialect.has_sequence(self.connection, sequence.name)): + if ((not self.dialect.sequences_optional or + not sequence.optional) and + (not self.checkfirst or + self.dialect.has_sequence(self.connection, sequence.name))): self.connection.execute(schema.DropSequence(sequence)) diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py index d938c644f5..cd47f90bf7 100644 --- a/lib/sqlalchemy/engine/default.py +++ b/lib/sqlalchemy/engine/default.py @@ -20,6 +20,7 @@ from sqlalchemy import exc, types as sqltypes AUTOCOMMIT_REGEXP = re.compile(r'\s*(?:UPDATE|INSERT|CREATE|DELETE|DROP|ALTER)', re.I | re.UNICODE) + class DefaultDialect(base.Dialect): """Default implementation of Dialect""" @@ -31,7 +32,7 @@ class DefaultDialect(base.Dialect): supports_alter = True supports_sequences = False sequences_optional = False - + # Py3K #supports_unicode_statements = True #supports_unicode_binds = True @@ -39,7 +40,7 @@ class DefaultDialect(base.Dialect): supports_unicode_statements = False supports_unicode_binds = False # end Py2K - + name = 'default' max_identifier_length = 9999 supports_sane_rowcount = True @@ -48,11 +49,11 @@ class DefaultDialect(base.Dialect): supports_pk_autoincrement = True dbapi_type_map = {} default_paramstyle = 'named' - supports_default_values = False + supports_default_values = False supports_empty_insert = True def __init__(self, convert_unicode=False, assert_unicode=False, - encoding='utf-8', paramstyle=None, dbapi=None, + encoding='utf-8', paramstyle=None, dbapi=None, label_length=None, **kwargs): self.convert_unicode = convert_unicode self.assert_unicode = assert_unicode @@ -69,15 +70,16 @@ class DefaultDialect(base.Dialect): self.positional = self.paramstyle in ('qmark', 'format', 'numeric') self.identifier_preparer = self.preparer(self) self.type_compiler = self.type_compiler(self) - + if label_length and label_length > self.max_identifier_length: raise exc.ArgumentError("Label length of %d is greater than this dialect's" - " maximum identifier length of %d" % (label_length, self.max_identifier_length)) + " maximum identifier length of %d" % + (label_length, self.max_identifier_length)) self.label_length = label_length - + if not hasattr(self, 'description_encoding'): self.description_encoding = getattr(self, 'description_encoding', encoding) - + # Py3K #self.supports_unicode_statements = True #self.supports_unicode_binds = True @@ -86,16 +88,16 @@ class DefaultDialect(base.Dialect): # TODO: all dialects need to implement this if hasattr(self, '_get_server_version_info'): self.server_version_info = self._get_server_version_info(connection) - + @classmethod def type_descriptor(cls, typeobj): """Provide a database-specific ``TypeEngine`` object, given the generic object which comes from the types module. - This method looks for a dictionary called + This method looks for a dictionary called ``colspecs`` as a class or instance-level variable, and passes on to ``types.adapt_type()``. - + """ return sqltypes.adapt_type(typeobj, cls.colspecs) @@ -131,7 +133,8 @@ class DefaultDialect(base.Dialect): """Create a random two-phase transaction ID. This id will be passed to do_begin_twophase(), do_rollback_twophase(), - do_commit_twophase(). Its format is unspecified.""" + do_commit_twophase(). Its format is unspecified. + """ return "_sa_%032x" % random.randint(0, 2 ** 128) @@ -239,9 +242,10 @@ class DefaultExecutionContext(base.ExecutionContext): return self._connection._branch() def __encode_param_keys(self, params): - """apply string encoding to the keys of dictionary-based bind parameters. + """Apply string encoding to the keys of dictionary-based bind parameters. - This is only used executing textual, non-compiled SQL expressions.""" + This is only used executing textual, non-compiled SQL expressions. + """ if self.dialect.positional or self.dialect.supports_unicode_statements: if params: @@ -260,7 +264,7 @@ class DefaultExecutionContext(base.ExecutionContext): return [proc(d) for d in params] or [{}] def __convert_compiled_params(self, compiled_parameters): - """convert the dictionary of bind parameter values into a dict or list + """Convert the dictionary of bind parameter values into a dict or list to be sent to the DBAPI's execute() or executemany() method. """ @@ -306,7 +310,7 @@ class DefaultExecutionContext(base.ExecutionContext): def post_exec(self): pass - + def handle_dbapi_exception(self, e): pass @@ -318,7 +322,7 @@ class DefaultExecutionContext(base.ExecutionContext): return self._rowcount else: return self.cursor.rowcount - + def supports_sane_rowcount(self): return self.dialect.supports_sane_rowcount @@ -341,12 +345,11 @@ class DefaultExecutionContext(base.ExecutionContext): """Given a cursor and ClauseParameters, call the appropriate style of ``setinputsizes()`` on the cursor, using DB-API types from the bind parameter's ``TypeEngine`` objects. - """ if not hasattr(self.compiled, 'bind_names'): return - + types = dict( (self.compiled.bind_names[bindparam], bindparam.type) for bindparam in self.compiled.bind_names) @@ -379,8 +382,9 @@ class DefaultExecutionContext(base.ExecutionContext): raise def __process_defaults(self): - """generate default values for compiled insert/update statements, - and generate last_inserted_ids() collection.""" + """Generate default values for compiled insert/update statements, + and generate last_inserted_ids() collection. + """ if self.executemany: if len(self.compiled.prefetch): diff --git a/lib/sqlalchemy/engine/reflection.py b/lib/sqlalchemy/engine/reflection.py index 611e97bcf0..69945fab36 100644 --- a/lib/sqlalchemy/engine/reflection.py +++ b/lib/sqlalchemy/engine/reflection.py @@ -2,22 +2,22 @@ Usage Notes: - Here are some general conventions when accessing the low level inspector methods such as get_table_names, get_columns, etc. - 1. Inspector methods return lists of dicts in most cases for the following - reasons: - * They're both standard types that can be serialized. - * Using a dict instead of a tuple allows easy expansion of attributes. - * Using a list for the outer structure maintains order and is easy to work - with (e.g. list comprehension [d['name'] for d in cols]). - 2. Records that contain a name, such as the column name in a column record - use the key 'name'. So for most return values, each record will have a - 'name' attribute.. +1. Inspector methods return lists of dicts in most cases for the following + reasons: + * They're both standard types that can be serialized. + * Using a dict instead of a tuple allows easy expansion of attributes. + * Using a list for the outer structure maintains order and is easy to work + with (e.g. list comprehension [d['name'] for d in cols]). +2. Records that contain a name, such as the column name in a column record + use the key 'name'. So for most return values, each record will have a + 'name' attribute.. """ + import sqlalchemy from sqlalchemy import util from sqlalchemy.types import TypeEngine @@ -41,16 +41,14 @@ class Inspector(object): The Inspector acts as a proxy to the dialects' reflection methods and provides higher level functions for accessing database schema information. - """ - - def __init__(self, conn): - """ - conn - [sqlalchemy.engine.base.#Connectable] + def __init__(self, conn): + """Initialize the instance. + :param conn: a :class:`~sqlalchemy.engine.base.Connectable` """ + self.conn = conn # set the engine if hasattr(conn, 'engine'): @@ -65,15 +63,15 @@ class Inspector(object): if hasattr(engine.dialect, 'inspector'): return engine.dialect.inspector(engine) return Inspector(engine) - + @property def default_schema_name(self): return self.dialect.get_default_schema_name(self.conn) def get_schema_names(self): """Return all schema names. - """ + if hasattr(self.dialect, 'get_schema_names'): return self.dialect.get_schema_names(self.conn, info_cache=self.info_cache) @@ -81,13 +79,15 @@ class Inspector(object): def get_table_names(self, schema=None, order_by=None): """Return all table names in `schema`. - schema: - Optional, retrieve names from a non-default schema. + + :param schema: Optional, retrieve names from a non-default schema. + :param order_by: Optional, may be the string "foreign_key" to sort + the result on foreign key dependencies. This should probably not return view names or maybe it should return them with an indicator t or v. - """ + if hasattr(self.dialect, 'get_table_names'): tnames = self.dialect.get_table_names(self.conn, schema, @@ -115,19 +115,19 @@ class Inspector(object): def get_view_names(self, schema=None): """Return all view names in `schema`. - schema: - Optional, retrieve names from a non-default schema. + :param schema: Optional, retrieve names from a non-default schema. """ + return self.dialect.get_view_names(self.conn, schema, info_cache=self.info_cache) def get_view_definition(self, view_name, schema=None): """Return definition for `view_name`. - schema: - Optional, retrieve names from a non-default schema. + :param schema: Optional, retrieve names from a non-default schema. """ + return self.dialect.get_view_definition( self.conn, view_name, schema, info_cache=self.info_cache) @@ -141,7 +141,7 @@ class Inspector(object): the column's name type - [sqlalchemy.types#TypeEngine] + :class:`~sqlalchemy.types.TypeEngine` nullable boolean @@ -151,7 +151,6 @@ class Inspector(object): attrs dict containing optional column attributes - """ col_defs = self.dialect.get_columns(self.conn, table_name, @@ -167,9 +166,8 @@ class Inspector(object): def get_primary_keys(self, table_name, schema=None): """Return information about primary keys in `table_name`. - Given a string `table_name`, and an optional string `schema`, return + Given a string `table_name`, and an optional string `schema`, return primary key information as a list of column names. - """ pkeys = self.dialect.get_primary_keys(self.conn, table_name, @@ -181,7 +179,7 @@ class Inspector(object): def get_foreign_keys(self, table_name, schema=None): """Return information about foreign_keys in `table_name`. - Given a string `table_name`, and an optional string `schema`, return + Given a string `table_name`, and an optional string `schema`, return foreign key information as a list of dicts with these keys: constrained_columns @@ -196,7 +194,6 @@ class Inspector(object): referred_columns a list of column names in the referred table that correspond to constrained_columns - """ fk_defs = self.dialect.get_foreign_keys(self.conn, table_name, @@ -228,7 +225,6 @@ class Inspector(object): unique boolean - """ indexes = self.dialect.get_indexes(self.conn, table_name, diff --git a/lib/sqlalchemy/engine/strategies.py b/lib/sqlalchemy/engine/strategies.py index c57acf242f..e62b01116e 100644 --- a/lib/sqlalchemy/engine/strategies.py +++ b/lib/sqlalchemy/engine/strategies.py @@ -6,8 +6,8 @@ underlying behavior for the "strategy" keyword argument available on ``plain``, ``threadlocal``, and ``mock``. New strategies can be added via new ``EngineStrategy`` classes. - """ + from operator import attrgetter from sqlalchemy.engine import base, threadlocal, url @@ -16,6 +16,7 @@ from sqlalchemy import pool as poollib strategies = {} + class EngineStrategy(object): """An adaptor that processes input arguements and produces an Engine. @@ -37,6 +38,7 @@ class EngineStrategy(object): raise NotImplementedError() + class DefaultEngineStrategy(EngineStrategy): """Base class for built-in stratgies.""" @@ -141,6 +143,7 @@ class DefaultEngineStrategy(EngineStrategy): def get_engine_cls(self): raise NotImplementedError() + class PlainEngineStrategy(DefaultEngineStrategy): """Strategy for configuring a regular Engine.""" @@ -155,6 +158,7 @@ class PlainEngineStrategy(DefaultEngineStrategy): PlainEngineStrategy() + class ThreadLocalEngineStrategy(DefaultEngineStrategy): """Strategy for configuring an Engine with thredlocal behavior.""" diff --git a/lib/sqlalchemy/engine/threadlocal.py b/lib/sqlalchemy/engine/threadlocal.py index 23c9cd0c1e..ec1a8f5f85 100644 --- a/lib/sqlalchemy/engine/threadlocal.py +++ b/lib/sqlalchemy/engine/threadlocal.py @@ -8,6 +8,7 @@ invoked automatically when the threadlocal engine strategy is used. from sqlalchemy import util from sqlalchemy.engine import base + class TLSession(object): def __init__(self, engine): self.engine = engine @@ -17,7 +18,8 @@ class TLSession(object): try: return self.__transaction._increment_connect() except AttributeError: - return self.engine.TLConnection(self, self.engine.pool.connect(), close_with_result=close_with_result) + return self.engine.TLConnection(self, self.engine.pool.connect(), + close_with_result=close_with_result) def reset(self): try: diff --git a/lib/sqlalchemy/engine/url.py b/lib/sqlalchemy/engine/url.py index 8000cbc6c3..157f914db8 100644 --- a/lib/sqlalchemy/engine/url.py +++ b/lib/sqlalchemy/engine/url.py @@ -20,9 +20,9 @@ class URL(object): format of the URL is an RFC-1738-style string. All initialization parameters are available as public attributes. - - :param drivername: the name of the database backend. - This name will correspond to a module in sqlalchemy/databases + + :param drivername: the name of the database backend. + This name will correspond to a module in sqlalchemy/databases or a third party plug-in. :param username: The user name. @@ -35,12 +35,13 @@ class URL(object): :param database: The database name. - :param query: A dictionary of options to be passed to the + :param query: A dictionary of options to be passed to the dialect and/or the DBAPI upon connect. - + """ - def __init__(self, drivername, username=None, password=None, host=None, port=None, database=None, query=None): + def __init__(self, drivername, username=None, password=None, + host=None, port=None, database=None, query=None): self.drivername = drivername self.username = username self.password = password @@ -70,10 +71,10 @@ class URL(object): keys.sort() s += '?' + "&".join("%s=%s" % (k, self.query[k]) for k in keys) return s - + def __hash__(self): return hash(str(self)) - + def __eq__(self, other): return \ isinstance(other, URL) and \ @@ -83,10 +84,12 @@ class URL(object): self.host == other.host and \ self.database == other.database and \ self.query == other.query - + def get_dialect(self): - """Return the SQLAlchemy database dialect class corresponding to this URL's driver name.""" - + """Return the SQLAlchemy database dialect class corresponding + to this URL's driver name. + """ + try: if '+' in self.drivername: dialect, driver = self.drivername.split('+') @@ -96,7 +99,7 @@ class URL(object): module = __import__('sqlalchemy.dialects.%s.%s' % (dialect, driver)).dialects module = getattr(module, dialect) module = getattr(module, driver) - + return module.dialect except ImportError: if sys.exc_info()[2].tb_next is None: @@ -105,7 +108,7 @@ class URL(object): if res.name == self.drivername: return res.load() raise - + def translate_connect_args(self, names=[], **kw): """Translate url attributes into a dictionary of connection arguments. @@ -115,10 +118,9 @@ class URL(object): from the final dictionary. :param \**kw: Optional, alternate key names for url attributes. - + :param names: Deprecated. Same purpose as the keyword-based alternate names, but correlates the name to the original positionally. - """ translated = {} @@ -139,8 +141,8 @@ def make_url(name_or_url): The given string is parsed according to the RFC 1738 spec. If an existing URL object is passed, just returns the object. - """ + if isinstance(name_or_url, basestring): return _parse_rfc1738_args(name_or_url) else: -- 2.47.3