diff options
Diffstat (limited to 'lib/sqlalchemy/databases')
-rw-r--r-- | lib/sqlalchemy/databases/access.py | 8 | ||||
-rw-r--r-- | lib/sqlalchemy/databases/firebird.py | 42 | ||||
-rw-r--r-- | lib/sqlalchemy/databases/informix.py | 41 | ||||
-rw-r--r-- | lib/sqlalchemy/databases/mssql.py | 46 | ||||
-rw-r--r-- | lib/sqlalchemy/databases/mysql.py | 36 | ||||
-rw-r--r-- | lib/sqlalchemy/databases/oracle.py | 56 | ||||
-rw-r--r-- | lib/sqlalchemy/databases/postgres.py | 48 | ||||
-rw-r--r-- | lib/sqlalchemy/databases/sqlite.py | 41 |
8 files changed, 137 insertions, 181 deletions
diff --git a/lib/sqlalchemy/databases/access.py b/lib/sqlalchemy/databases/access.py index 6bf8b96e9..4aa773239 100644 --- a/lib/sqlalchemy/databases/access.py +++ b/lib/sqlalchemy/databases/access.py @@ -347,7 +347,7 @@ class AccessDialect(ansisql.ANSIDialect): return names -class AccessCompiler(ansisql.ANSICompiler): +class AccessCompiler(compiler.DefaultCompiler): def visit_select_precolumns(self, select): """Access puts TOP, it's version of LIMIT here """ s = select.distinct and "DISTINCT " or "" @@ -387,7 +387,7 @@ class AccessCompiler(ansisql.ANSICompiler): return '' -class AccessSchemaGenerator(ansisql.ANSISchemaGenerator): +class AccessSchemaGenerator(compiler.SchemaGenerator): def get_column_specification(self, column, **kwargs): colspec = self.preparer.format_column(column) + " " + column.type.dialect_impl(self.dialect).get_col_spec() @@ -410,7 +410,7 @@ class AccessSchemaGenerator(ansisql.ANSISchemaGenerator): return colspec -class AccessSchemaDropper(ansisql.ANSISchemaDropper): +class AccessSchemaDropper(compiler.SchemaDropper): def visit_index(self, index): self.append("\nDROP INDEX [%s].[%s]" % (index.table.name, index.name)) self.execute() @@ -418,7 +418,7 @@ class AccessSchemaDropper(ansisql.ANSISchemaDropper): class AccessDefaultRunner(ansisql.ANSIDefaultRunner): pass -class AccessIdentifierPreparer(ansisql.ANSIIdentifierPreparer): +class AccessIdentifierPreparer(compiler.IdentifierPreparer): def __init__(self, dialect): super(AccessIdentifierPreparer, self).__init__(dialect, initial_quote='[', final_quote=']') diff --git a/lib/sqlalchemy/databases/firebird.py b/lib/sqlalchemy/databases/firebird.py index 307fceb48..9cccb53e8 100644 --- a/lib/sqlalchemy/databases/firebird.py +++ b/lib/sqlalchemy/databases/firebird.py @@ -7,9 +7,10 @@ import warnings -from sqlalchemy import util, sql, schema, ansisql, exceptions -import sqlalchemy.engine.default as default -import sqlalchemy.types as sqltypes +from sqlalchemy import util, sql, schema, exceptions +from sqlalchemy.sql import compiler +from sqlalchemy.engine import default, base +from sqlalchemy import types as sqltypes _initialized_kb = False @@ -99,9 +100,9 @@ class FBExecutionContext(default.DefaultExecutionContext): return True -class FBDialect(ansisql.ANSIDialect): +class FBDialect(default.DefaultDialect): def __init__(self, type_conv=200, concurrency_level=1, **kwargs): - ansisql.ANSIDialect.__init__(self, **kwargs) + default.DefaultDialect.__init__(self, **kwargs) self.type_conv = type_conv self.concurrency_level= concurrency_level @@ -135,21 +136,6 @@ class FBDialect(ansisql.ANSIDialect): def supports_sane_rowcount(self): return False - def compiler(self, statement, bindparams, **kwargs): - return FBCompiler(self, statement, bindparams, **kwargs) - - def schemagenerator(self, *args, **kwargs): - return FBSchemaGenerator(self, *args, **kwargs) - - def schemadropper(self, *args, **kwargs): - return FBSchemaDropper(self, *args, **kwargs) - - def defaultrunner(self, connection): - return FBDefaultRunner(connection) - - def preparer(self): - return FBIdentifierPreparer(self) - def max_identifier_length(self): return 31 @@ -307,7 +293,7 @@ class FBDialect(ansisql.ANSIDialect): connection.commit(True) -class FBCompiler(ansisql.ANSICompiler): +class FBCompiler(compiler.DefaultCompiler): """Firebird specific idiosincrasies""" def visit_alias(self, alias, asfrom=False, **kwargs): @@ -346,7 +332,7 @@ class FBCompiler(ansisql.ANSICompiler): return "" -class FBSchemaGenerator(ansisql.ANSISchemaGenerator): +class FBSchemaGenerator(compiler.SchemaGenerator): def get_column_specification(self, column, **kwargs): colspec = self.preparer.format_column(column) colspec += " " + column.type.dialect_impl(self.dialect).get_col_spec() @@ -365,13 +351,13 @@ class FBSchemaGenerator(ansisql.ANSISchemaGenerator): self.execute() -class FBSchemaDropper(ansisql.ANSISchemaDropper): +class FBSchemaDropper(compiler.SchemaDropper): def visit_sequence(self, sequence): self.append("DROP GENERATOR %s" % sequence.name) self.execute() -class FBDefaultRunner(ansisql.ANSIDefaultRunner): +class FBDefaultRunner(base.DefaultRunner): def exec_default_sql(self, default): c = sql.select([default.arg], from_obj=["rdb$database"]).compile(bind=self.connection) return self.connection.execute_compiled(c).scalar() @@ -421,7 +407,7 @@ RESERVED_WORDS = util.Set( "whenever", "where", "while", "with", "work", "write", "year", "yearday" ]) -class FBIdentifierPreparer(ansisql.ANSIIdentifierPreparer): +class FBIdentifierPreparer(compiler.IdentifierPreparer): def __init__(self, dialect): super(FBIdentifierPreparer,self).__init__(dialect, omit_schema=True) @@ -430,3 +416,9 @@ class FBIdentifierPreparer(ansisql.ANSIIdentifierPreparer): dialect = FBDialect +dialect.statement_compiler = FBCompiler +dialect.schemagenerator = FBSchemaGenerator +dialect.schemadropper = FBSchemaDropper +dialect.defaultrunner = FBDefaultRunner +dialect.preparer = FBIdentifierPreparer + diff --git a/lib/sqlalchemy/databases/informix.py b/lib/sqlalchemy/databases/informix.py index 21ecf1538..ceb56903a 100644 --- a/lib/sqlalchemy/databases/informix.py +++ b/lib/sqlalchemy/databases/informix.py @@ -7,9 +7,10 @@ import datetime, warnings -from sqlalchemy import sql, schema, ansisql, exceptions, pool -import sqlalchemy.engine.default as default -import sqlalchemy.types as sqltypes +from sqlalchemy import sql, schema, exceptions, pool +from sqlalchemy.sql import compiler +from sqlalchemy.engine import default +from sqlalchemy import types as sqltypes # for offset @@ -203,11 +204,11 @@ class InfoExecutionContext(default.DefaultExecutionContext): def create_cursor( self ): return informix_cursor( self.connection.connection ) -class InfoDialect(ansisql.ANSIDialect): +class InfoDialect(default.DefaultDialect): def __init__(self, use_ansi=True,**kwargs): self.use_ansi = use_ansi - ansisql.ANSIDialect.__init__(self, **kwargs) + default.DefaultDialect.__init__(self, **kwargs) self.paramstyle = 'qmark' def dbapi(cls): @@ -252,18 +253,6 @@ class InfoDialect(ansisql.ANSIDialect): def oid_column_name(self,column): return "rowid" - def preparer(self): - return InfoIdentifierPreparer(self) - - def compiler(self, statement, bindparams, **kwargs): - return InfoCompiler(self, statement, bindparams, **kwargs) - - def schemagenerator(self, *args, **kwargs): - return InfoSchemaGenerator( self , *args, **kwargs) - - def schemadropper(self, *args, **params): - return InfoSchemaDroper( self , *args , **params) - def table_names(self, connection, schema): s = "select tabname from systables" return [row[0] for row in connection.execute(s)] @@ -376,14 +365,14 @@ class InfoDialect(ansisql.ANSIDialect): for cons_name, cons_type, local_column in rows: table.primary_key.add( table.c[local_column] ) -class InfoCompiler(ansisql.ANSICompiler): +class InfoCompiler(compiler.DefaultCompiler): """Info compiler modifies the lexical structure of Select statements to work under non-ANSI configured Oracle databases, if the use_ansi flag is False.""" def __init__(self, dialect, statement, parameters=None, **kwargs): self.limit = 0 self.offset = 0 - ansisql.ANSICompiler.__init__( self , dialect , statement , parameters , **kwargs ) + compiler.DefaultCompiler.__init__( self , dialect , statement , parameters , **kwargs ) def default_from(self): return " from systables where tabname = 'systables' " @@ -416,7 +405,7 @@ class InfoCompiler(ansisql.ANSICompiler): if ( __label(c) not in a ) and getattr( c , 'name' , '' ) != 'oid': select.append_column( c ) - return ansisql.ANSICompiler.visit_select(self, select) + return compiler.DefaultCompiler.visit_select(self, select) def limit_clause(self, select): return "" @@ -437,7 +426,7 @@ class InfoCompiler(ansisql.ANSICompiler): elif func.name.lower() in ( 'current_timestamp' , 'now' ): return "CURRENT YEAR TO SECOND" else: - return ansisql.ANSICompiler.visit_function( self , func ) + return compiler.DefaultCompiler.visit_function( self , func ) def visit_clauselist(self, list): try: @@ -446,7 +435,7 @@ class InfoCompiler(ansisql.ANSICompiler): li = [ c for c in list.clauses ] return ', '.join([s for s in [self.process(c) for c in li] if s is not None]) -class InfoSchemaGenerator(ansisql.ANSISchemaGenerator): +class InfoSchemaGenerator(compiler.SchemaGenerator): def get_column_specification(self, column, first_pk=False): colspec = self.preparer.format_column(column) if column.primary_key and len(column.foreign_keys)==0 and column.autoincrement and \ @@ -507,7 +496,7 @@ class InfoSchemaGenerator(ansisql.ANSISchemaGenerator): return super(InfoSchemaGenerator, self).visit_index(index) -class InfoIdentifierPreparer(ansisql.ANSIIdentifierPreparer): +class InfoIdentifierPreparer(compiler.IdentifierPreparer): def __init__(self, dialect): super(InfoIdentifierPreparer, self).__init__(dialect, initial_quote="'") @@ -517,10 +506,14 @@ class InfoIdentifierPreparer(ansisql.ANSIIdentifierPreparer): def _requires_quotes(self, value): return False -class InfoSchemaDroper(ansisql.ANSISchemaDropper): +class InfoSchemaDroper(compiler.SchemaDropper): def drop_foreignkey(self, constraint): if constraint.name is not None: super( InfoSchemaDroper , self ).drop_foreignkey( constraint ) dialect = InfoDialect poolclass = pool.SingletonThreadPool +dialect.statement_compiler = InfoCompiler +dialect.schemagenerator = InfoSchemaGenerator +dialect.schemadropper = InfoSchemaDropper +dialect.preparer = InfoIdentifierPreparer diff --git a/lib/sqlalchemy/databases/mssql.py b/lib/sqlalchemy/databases/mssql.py index 619e072d9..0caccca95 100644 --- a/lib/sqlalchemy/databases/mssql.py +++ b/lib/sqlalchemy/databases/mssql.py @@ -39,10 +39,10 @@ Known issues / TODO: import datetime, random, warnings, re -from sqlalchemy import sql, schema, ansisql, exceptions -import sqlalchemy.types as sqltypes -from sqlalchemy.engine import default -import operator, sys +from sqlalchemy import util, sql, schema, exceptions +from sqlalchemy.sql import compiler, expression +from sqlalchemy.engine import default, base +from sqlalchemy import types as sqltypes class MSNumeric(sqltypes.Numeric): def result_processor(self, dialect): @@ -366,7 +366,7 @@ class MSSQLExecutionContext_pyodbc (MSSQLExecutionContext): super(MSSQLExecutionContext_pyodbc, self).post_exec() -class MSSQLDialect(ansisql.ANSIDialect): +class MSSQLDialect(default.DefaultDialect): colspecs = { sqltypes.Unicode : MSNVarchar, sqltypes.Integer : MSInteger, @@ -476,21 +476,6 @@ class MSSQLDialect(ansisql.ANSIDialect): def supports_sane_rowcount(self): raise NotImplementedError() - def compiler(self, statement, bindparams, **kwargs): - return MSSQLCompiler(self, statement, bindparams, **kwargs) - - def schemagenerator(self, *args, **kwargs): - return MSSQLSchemaGenerator(self, *args, **kwargs) - - def schemadropper(self, *args, **kwargs): - return MSSQLSchemaDropper(self, *args, **kwargs) - - def defaultrunner(self, connection, **kwargs): - return MSSQLDefaultRunner(connection, **kwargs) - - def preparer(self): - return MSSQLIdentifierPreparer(self) - def get_default_schema_name(self, connection): return self.schema_name @@ -878,7 +863,7 @@ dialect_mapping = { } -class MSSQLCompiler(ansisql.ANSICompiler): +class MSSQLCompiler(compiler.DefaultCompiler): def __init__(self, dialect, statement, parameters, **kwargs): super(MSSQLCompiler, self).__init__(dialect, statement, parameters, **kwargs) self.tablealiases = {} @@ -931,13 +916,13 @@ class MSSQLCompiler(ansisql.ANSICompiler): def visit_binary(self, binary): """Move bind parameters to the right-hand side of an operator, where possible.""" - if isinstance(binary.left, sql._BindParamClause) and binary.operator == operator.eq: - return self.process(sql._BinaryExpression(binary.right, binary.left, binary.operator)) + if isinstance(binary.left, expression._BindParamClause) and binary.operator == operator.eq: + return self.process(expression._BinaryExpression(binary.right, binary.left, binary.operator)) else: return super(MSSQLCompiler, self).visit_binary(binary) def label_select_column(self, select, column): - if isinstance(column, sql._Function): + if isinstance(column, expression._Function): return column.label(column.name + "_" + hex(random.randint(0, 65535))[2:]) else: return super(MSSQLCompiler, self).label_select_column(select, column) @@ -963,7 +948,7 @@ class MSSQLCompiler(ansisql.ANSICompiler): return "" -class MSSQLSchemaGenerator(ansisql.ANSISchemaGenerator): +class MSSQLSchemaGenerator(compiler.SchemaGenerator): def get_column_specification(self, column, **kwargs): colspec = self.preparer.format_column(column) + " " + column.type.dialect_impl(self.dialect).get_col_spec() @@ -986,7 +971,7 @@ class MSSQLSchemaGenerator(ansisql.ANSISchemaGenerator): return colspec -class MSSQLSchemaDropper(ansisql.ANSISchemaDropper): +class MSSQLSchemaDropper(compiler.SchemaDropper): def visit_index(self, index): self.append("\nDROP INDEX %s.%s" % ( self.preparer.quote_identifier(index.table.name), @@ -995,11 +980,11 @@ class MSSQLSchemaDropper(ansisql.ANSISchemaDropper): self.execute() -class MSSQLDefaultRunner(ansisql.ANSIDefaultRunner): +class MSSQLDefaultRunner(base.DefaultRunner): # TODO: does ms-sql have standalone sequences ? pass -class MSSQLIdentifierPreparer(ansisql.ANSIIdentifierPreparer): +class MSSQLIdentifierPreparer(compiler.IdentifierPreparer): def __init__(self, dialect): super(MSSQLIdentifierPreparer, self).__init__(dialect, initial_quote='[', final_quote=']') @@ -1012,6 +997,11 @@ class MSSQLIdentifierPreparer(ansisql.ANSIIdentifierPreparer): return value dialect = MSSQLDialect +dialect.statement_compiler = MSSQLCompiler +dialect.schemagenerator = MSSQLSchemaGenerator +dialect.schemadropper = MSSQLSchemaDropper +dialect.preparer = MSSQLIdentifierPreparer +dialect.defaultrunner = MSSQLDefaultRunner diff --git a/lib/sqlalchemy/databases/mysql.py b/lib/sqlalchemy/databases/mysql.py index d5fd3b6c5..41c6ec70f 100644 --- a/lib/sqlalchemy/databases/mysql.py +++ b/lib/sqlalchemy/databases/mysql.py @@ -126,11 +126,12 @@ information affecting MySQL in SQLAlchemy. import re, datetime, inspect, warnings, sys from array import array as _array -from sqlalchemy import ansisql, exceptions, logging, schema, sql, util -from sqlalchemy import operators as sql_operators +from sqlalchemy import exceptions, logging, schema, sql, util +from sqlalchemy.sql import operators as sql_operators +from sqlalchemy.sql import compiler from sqlalchemy.engine import base as engine_base, default -import sqlalchemy.types as sqltypes +from sqlalchemy import types as sqltypes __all__ = ( @@ -1328,13 +1329,17 @@ class MySQLExecutionContext(default.DefaultExecutionContext): return AUTOCOMMIT_RE.match(self.statement) -class MySQLDialect(ansisql.ANSIDialect): +class MySQLDialect(default.DefaultDialect): """Details of the MySQL dialect. Not used directly in application code.""" def __init__(self, use_ansiquotes=False, **kwargs): self.use_ansiquotes = use_ansiquotes kwargs.setdefault('default_paramstyle', 'format') - ansisql.ANSIDialect.__init__(self, **kwargs) + if self.use_ansiquotes: + self.preparer = MySQLANSIIdentifierPreparer + else: + self.preparer = MySQLIdentifierPreparer + default.DefaultDialect.__init__(self, **kwargs) def dbapi(cls): import MySQLdb as mysql @@ -1393,7 +1398,7 @@ class MySQLDialect(ansisql.ANSIDialect): return True def compiler(self, statement, bindparams, **kwargs): - return MySQLCompiler(self, statement, bindparams, **kwargs) + return MySQLCompiler(statement, bindparams, dialect=self, **kwargs) def schemagenerator(self, *args, **kwargs): return MySQLSchemaGenerator(self, *args, **kwargs) @@ -1401,12 +1406,6 @@ class MySQLDialect(ansisql.ANSIDialect): def schemadropper(self, *args, **kwargs): return MySQLSchemaDropper(self, *args, **kwargs) - def preparer(self): - if self.use_ansiquotes: - return MySQLANSIIdentifierPreparer(self) - else: - return MySQLIdentifierPreparer(self) - def do_executemany(self, cursor, statement, parameters, context=None, **kwargs): rowcount = cursor.executemany(statement, parameters) @@ -1733,8 +1732,8 @@ class _MySQLPythonRowProxy(object): return item -class MySQLCompiler(ansisql.ANSICompiler): - operators = ansisql.ANSICompiler.operators.copy() +class MySQLCompiler(compiler.DefaultCompiler): + operators = compiler.DefaultCompiler.operators.copy() operators.update( { sql_operators.concat_op: \ @@ -1783,7 +1782,7 @@ class MySQLCompiler(ansisql.ANSICompiler): # In older versions, the indexes must be created explicitly or the # creation of foreign key constraints fails." -class MySQLSchemaGenerator(ansisql.ANSISchemaGenerator): +class MySQLSchemaGenerator(compiler.SchemaGenerator): def get_column_specification(self, column, override_pk=False, first_pk=False): """Builds column DDL.""" @@ -1827,7 +1826,7 @@ class MySQLSchemaGenerator(ansisql.ANSISchemaGenerator): return ' '.join(table_opts) -class MySQLSchemaDropper(ansisql.ANSISchemaDropper): +class MySQLSchemaDropper(compiler.SchemaDropper): def visit_index(self, index): self.append("\nDROP INDEX %s ON %s" % (self.preparer.format_index(index), @@ -2368,7 +2367,7 @@ class MySQLSchemaReflector(object): MySQLSchemaReflector.logger = logging.class_logger(MySQLSchemaReflector) -class _MySQLIdentifierPreparer(ansisql.ANSIIdentifierPreparer): +class _MySQLIdentifierPreparer(compiler.IdentifierPreparer): """MySQL-specific schema identifier configuration.""" def __init__(self, dialect, **kw): @@ -2433,3 +2432,6 @@ def _re_compile(regex): return re.compile(regex, re.I | re.UNICODE) dialect = MySQLDialect +dialect.statement_compiler = MySQLCompiler +dialect.schemagenerator = MySQLSchemaGenerator +dialect.schemadropper = MySQLSchemaDropper diff --git a/lib/sqlalchemy/databases/oracle.py b/lib/sqlalchemy/databases/oracle.py index a35db1982..2d8f2940f 100644 --- a/lib/sqlalchemy/databases/oracle.py +++ b/lib/sqlalchemy/databases/oracle.py @@ -5,11 +5,13 @@ # the MIT License: http://www.opensource.org/licenses/mit-license.php -import re, warnings, operator, random +import re, warnings, random -from sqlalchemy import util, sql, schema, ansisql, exceptions, logging +from sqlalchemy import util, sql, schema, exceptions, logging from sqlalchemy.engine import default, base -import sqlalchemy.types as sqltypes +from sqlalchemy.sql import compiler, visitors +from sqlalchemy.sql import operators as sql_operators +from sqlalchemy import types as sqltypes import datetime @@ -229,9 +231,9 @@ class OracleExecutionContext(default.DefaultExecutionContext): return base.ResultProxy(self) -class OracleDialect(ansisql.ANSIDialect): +class OracleDialect(default.DefaultDialect): def __init__(self, use_ansi=True, auto_setinputsizes=True, auto_convert_lobs=True, threaded=True, allow_twophase=True, **kwargs): - ansisql.ANSIDialect.__init__(self, default_paramstyle='named', **kwargs) + default.DefaultDialect.__init__(self, default_paramstyle='named', **kwargs) self.use_ansi = use_ansi self.threaded = threaded self.allow_twophase = allow_twophase @@ -333,21 +335,6 @@ class OracleDialect(ansisql.ANSIDialect): def create_execution_context(self, *args, **kwargs): return OracleExecutionContext(self, *args, **kwargs) - def compiler(self, statement, bindparams, **kwargs): - return OracleCompiler(self, statement, bindparams, **kwargs) - - def preparer(self): - return OracleIdentifierPreparer(self) - - def schemagenerator(self, *args, **kwargs): - return OracleSchemaGenerator(self, *args, **kwargs) - - def schemadropper(self, *args, **kwargs): - return OracleSchemaDropper(self, *args, **kwargs) - - def defaultrunner(self, connection, **kwargs): - return OracleDefaultRunner(connection, **kwargs) - def has_table(self, connection, table_name, schema=None): cursor = connection.execute("""select table_name from all_tables where table_name=:name""", {'name':self._denormalize_name(table_name)}) return bool( cursor.fetchone() is not None ) @@ -560,16 +547,16 @@ class _OuterJoinColumn(sql.ClauseElement): def __init__(self, column): self.column = column -class OracleCompiler(ansisql.ANSICompiler): +class OracleCompiler(compiler.DefaultCompiler): """Oracle compiler modifies the lexical structure of Select statements to work under non-ANSI configured Oracle databases, if the use_ansi flag is False. """ - operators = ansisql.ANSICompiler.operators.copy() + operators = compiler.DefaultCompiler.operators.copy() operators.update( { - operator.mod : lambda x, y:"mod(%s, %s)" % (x, y) + sql_operators.mod : lambda x, y:"mod(%s, %s)" % (x, y) } ) @@ -590,13 +577,13 @@ class OracleCompiler(ansisql.ANSICompiler): def visit_join(self, join, **kwargs): if self.dialect.use_ansi: - return ansisql.ANSICompiler.visit_join(self, join, **kwargs) + return compiler.DefaultCompiler.visit_join(self, join, **kwargs) (where, parentjoin) = self.__wheres.get(join, (None, None)) - class VisitOn(sql.ClauseVisitor): + class VisitOn(visitors.ClauseVisitor): def visit_binary(s, binary): - if binary.operator == operator.eq: + if binary.operator == sql_operators.eq: if binary.left.table is join.right: binary.left = _OuterJoinColumn(binary.left) elif binary.right.table is join.right: @@ -640,7 +627,7 @@ class OracleCompiler(ansisql.ANSICompiler): for c in insert.table.primary_key: if c.key not in self.parameters: self.parameters[c.key] = None - return ansisql.ANSICompiler.visit_insert(self, insert) + return compiler.DefaultCompiler.visit_insert(self, insert) def _TODO_visit_compound_select(self, select): """Need to determine how to get ``LIMIT``/``OFFSET`` into a ``UNION`` for Oracle.""" @@ -672,7 +659,7 @@ class OracleCompiler(ansisql.ANSICompiler): limitselect.append_whereclause("ora_rn<=%d" % select._limit) return self.process(limitselect, **kwargs) else: - return ansisql.ANSICompiler.visit_select(self, select, **kwargs) + return compiler.DefaultCompiler.visit_select(self, select, **kwargs) def limit_clause(self, select): return "" @@ -684,7 +671,7 @@ class OracleCompiler(ansisql.ANSICompiler): return super(OracleCompiler, self).for_update_clause(select) -class OracleSchemaGenerator(ansisql.ANSISchemaGenerator): +class OracleSchemaGenerator(compiler.SchemaGenerator): def get_column_specification(self, column, **kwargs): colspec = self.preparer.format_column(column) colspec += " " + column.type.dialect_impl(self.dialect).get_col_spec() @@ -701,13 +688,13 @@ class OracleSchemaGenerator(ansisql.ANSISchemaGenerator): self.append("CREATE SEQUENCE %s" % self.preparer.format_sequence(sequence)) self.execute() -class OracleSchemaDropper(ansisql.ANSISchemaDropper): +class OracleSchemaDropper(compiler.SchemaDropper): def visit_sequence(self, sequence): if not self.checkfirst or self.dialect.has_sequence(self.connection, sequence.name): self.append("DROP SEQUENCE %s" % self.preparer.format_sequence(sequence)) self.execute() -class OracleDefaultRunner(ansisql.ANSIDefaultRunner): +class OracleDefaultRunner(base.DefaultRunner): def exec_default_sql(self, default): c = sql.select([default.arg], from_obj=["DUAL"]).compile(bind=self.connection) return self.connection.execute(c).scalar() @@ -715,10 +702,15 @@ class OracleDefaultRunner(ansisql.ANSIDefaultRunner): def visit_sequence(self, seq): return self.connection.execute("SELECT " + self.dialect.identifier_preparer.format_sequence(seq) + ".nextval FROM DUAL").scalar() -class OracleIdentifierPreparer(ansisql.ANSIIdentifierPreparer): +class OracleIdentifierPreparer(compiler.IdentifierPreparer): def format_savepoint(self, savepoint): name = re.sub(r'^_+', '', savepoint.ident) return super(OracleIdentifierPreparer, self).format_savepoint(savepoint, name) dialect = OracleDialect +dialect.statement_compiler = OracleCompiler +dialect.schemagenerator = OracleSchemaGenerator +dialect.schemadropper = OracleSchemaDropper +dialect.preparer = OracleIdentifierPreparer +dialect.defaultrunner = OracleDefaultRunner diff --git a/lib/sqlalchemy/databases/postgres.py b/lib/sqlalchemy/databases/postgres.py index 74a3ef13f..29d84ad4d 100644 --- a/lib/sqlalchemy/databases/postgres.py +++ b/lib/sqlalchemy/databases/postgres.py @@ -4,11 +4,13 @@ # This module is part of SQLAlchemy and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php -import re, random, warnings, operator +import re, random, warnings -from sqlalchemy import sql, schema, ansisql, exceptions, util +from sqlalchemy import sql, schema, exceptions, util from sqlalchemy.engine import base, default -import sqlalchemy.types as sqltypes +from sqlalchemy.sql import compiler +from sqlalchemy.sql import operators as sql_operators +from sqlalchemy import types as sqltypes class PGInet(sqltypes.TypeEngine): @@ -220,9 +222,9 @@ class PGExecutionContext(default.DefaultExecutionContext): self._last_inserted_ids = [v for v in row] super(PGExecutionContext, self).post_exec() -class PGDialect(ansisql.ANSIDialect): +class PGDialect(default.DefaultDialect): def __init__(self, use_oids=False, server_side_cursors=False, **kwargs): - ansisql.ANSIDialect.__init__(self, default_paramstyle='pyformat', **kwargs) + default.DefaultDialect.__init__(self, default_paramstyle='pyformat', **kwargs) self.use_oids = use_oids self.server_side_cursors = server_side_cursors self.paramstyle = 'pyformat' @@ -249,15 +251,6 @@ class PGDialect(ansisql.ANSIDialect): def type_descriptor(self, typeobj): return sqltypes.adapt_type(typeobj, colspecs) - def compiler(self, statement, bindparams, **kwargs): - return PGCompiler(self, statement, bindparams, **kwargs) - - def schemagenerator(self, *args, **kwargs): - return PGSchemaGenerator(self, *args, **kwargs) - - def schemadropper(self, *args, **kwargs): - return PGSchemaDropper(self, *args, **kwargs) - def do_begin_twophase(self, connection, xid): self.do_begin(connection.connection) @@ -286,12 +279,6 @@ class PGDialect(ansisql.ANSIDialect): resultset = connection.execute(sql.text("SELECT gid FROM pg_prepared_xacts")) return [row[0] for row in resultset] - def defaultrunner(self, context, **kwargs): - return PGDefaultRunner(context, **kwargs) - - def preparer(self): - return PGIdentifierPreparer(self) - def get_default_schema_name(self, connection): if not hasattr(self, '_default_schema_name'): self._default_schema_name = connection.scalar("select current_schema()", None) @@ -556,11 +543,11 @@ class PGDialect(ansisql.ANSIDialect): -class PGCompiler(ansisql.ANSICompiler): - operators = ansisql.ANSICompiler.operators.copy() +class PGCompiler(compiler.DefaultCompiler): + operators = compiler.DefaultCompiler.operators.copy() operators.update( { - operator.mod : '%%' + sql_operators.mod : '%%' } ) @@ -597,7 +584,7 @@ class PGCompiler(ansisql.ANSICompiler): else: return super(PGCompiler, self).for_update_clause(select) -class PGSchemaGenerator(ansisql.ANSISchemaGenerator): +class PGSchemaGenerator(compiler.SchemaGenerator): def get_column_specification(self, column, **kwargs): colspec = self.preparer.format_column(column) if column.primary_key and len(column.foreign_keys)==0 and column.autoincrement and isinstance(column.type, sqltypes.Integer) and not isinstance(column.type, sqltypes.SmallInteger) and (column.default is None or (isinstance(column.default, schema.Sequence) and column.default.optional)): @@ -620,13 +607,13 @@ class PGSchemaGenerator(ansisql.ANSISchemaGenerator): self.append("CREATE SEQUENCE %s" % self.preparer.format_sequence(sequence)) self.execute() -class PGSchemaDropper(ansisql.ANSISchemaDropper): +class PGSchemaDropper(compiler.SchemaDropper): def visit_sequence(self, sequence): if not sequence.optional and (not self.checkfirst or self.dialect.has_sequence(self.connection, sequence.name)): self.append("DROP SEQUENCE %s" % self.preparer.format_sequence(sequence)) self.execute() -class PGDefaultRunner(ansisql.ANSIDefaultRunner): +class PGDefaultRunner(base.DefaultRunner): def get_column_default(self, column, isinsert=True): if column.primary_key: # passive defaults on primary keys have to be overridden @@ -642,7 +629,7 @@ class PGDefaultRunner(ansisql.ANSIDefaultRunner): exc = "select nextval('\"%s_%s_seq\"')" % (column.table.name, column.name) return self.connection.execute(exc).scalar() - return super(ansisql.ANSIDefaultRunner, self).get_column_default(column) + return super(PGDefaultRunner, self).get_column_default(column) def visit_sequence(self, seq): if not seq.optional: @@ -650,7 +637,7 @@ class PGDefaultRunner(ansisql.ANSIDefaultRunner): else: return None -class PGIdentifierPreparer(ansisql.ANSIIdentifierPreparer): +class PGIdentifierPreparer(compiler.IdentifierPreparer): def _fold_identifier_case(self, value): return value.lower() @@ -660,3 +647,8 @@ class PGIdentifierPreparer(ansisql.ANSIIdentifierPreparer): return value dialect = PGDialect +dialect.statement_compiler = PGCompiler +dialect.schemagenerator = PGSchemaGenerator +dialect.schemadropper = PGSchemaDropper +dialect.preparer = PGIdentifierPreparer +dialect.defaultrunner = PGDefaultRunner diff --git a/lib/sqlalchemy/databases/sqlite.py b/lib/sqlalchemy/databases/sqlite.py index d96422236..c2aced4d0 100644 --- a/lib/sqlalchemy/databases/sqlite.py +++ b/lib/sqlalchemy/databases/sqlite.py @@ -7,11 +7,12 @@ import re -from sqlalchemy import schema, ansisql, exceptions, pool, PassiveDefault -import sqlalchemy.engine.default as default +from sqlalchemy import schema, exceptions, pool, PassiveDefault +from sqlalchemy.engine import default import sqlalchemy.types as sqltypes import datetime,time, warnings import sqlalchemy.util as util +from sqlalchemy.sql import compiler SELECT_REGEXP = re.compile(r'\s*(?:SELECT|PRAGMA)', re.I | re.UNICODE) @@ -172,10 +173,10 @@ class SQLiteExecutionContext(default.DefaultExecutionContext): def is_select(self): return SELECT_REGEXP.match(self.statement) -class SQLiteDialect(ansisql.ANSIDialect): +class SQLiteDialect(default.DefaultDialect): def __init__(self, **kwargs): - ansisql.ANSIDialect.__init__(self, default_paramstyle='qmark', **kwargs) + default.DefaultDialect.__init__(self, default_paramstyle='qmark', **kwargs) def vers(num): return tuple([int(x) for x in num.split('.')]) if self.dbapi is not None: @@ -195,24 +196,12 @@ class SQLiteDialect(ansisql.ANSIDialect): return sqlite dbapi = classmethod(dbapi) - def compiler(self, statement, bindparams, **kwargs): - return SQLiteCompiler(self, statement, bindparams, **kwargs) - - def schemagenerator(self, *args, **kwargs): - return SQLiteSchemaGenerator(self, *args, **kwargs) - - def schemadropper(self, *args, **kwargs): - return SQLiteSchemaDropper(self, *args, **kwargs) - def server_version_info(self, connection): return self.dbapi.sqlite_version_info def supports_alter(self): return False - def preparer(self): - return SQLiteIdentifierPreparer(self) - def create_connect_args(self, url): filename = url.database or ':memory:' @@ -255,7 +244,7 @@ class SQLiteDialect(ansisql.ANSIDialect): return (row is not None) def reflecttable(self, connection, table, include_columns): - c = connection.execute("PRAGMA table_info(%s)" % self.preparer().format_table(table), {}) + c = connection.execute("PRAGMA table_info(%s)" % self.identifier_preparer.format_table(table), {}) found_table = False while True: row = c.fetchone() @@ -295,7 +284,7 @@ class SQLiteDialect(ansisql.ANSIDialect): if not found_table: raise exceptions.NoSuchTableError(table.name) - c = connection.execute("PRAGMA foreign_key_list(%s)" % self.preparer().format_table(table), {}) + c = connection.execute("PRAGMA foreign_key_list(%s)" % self.identifier_preparer.format_table(table), {}) fks = {} while True: row = c.fetchone() @@ -324,7 +313,7 @@ class SQLiteDialect(ansisql.ANSIDialect): for name, value in fks.iteritems(): table.append_constraint(schema.ForeignKeyConstraint(value[0], value[1])) # check for UNIQUE indexes - c = connection.execute("PRAGMA index_list(%s)" % self.preparer().format_table(table), {}) + c = connection.execute("PRAGMA index_list(%s)" % self.identifier_preparer.format_table(table), {}) unique_indexes = [] while True: row = c.fetchone() @@ -343,7 +332,7 @@ class SQLiteDialect(ansisql.ANSIDialect): cols.append(row[2]) col = table.columns[row[2]] -class SQLiteCompiler(ansisql.ANSICompiler): +class SQLiteCompiler(compiler.DefaultCompiler): def visit_cast(self, cast): if self.dialect.supports_cast: return super(SQLiteCompiler, self).visit_cast(cast) @@ -369,7 +358,8 @@ class SQLiteCompiler(ansisql.ANSICompiler): # sqlite has no "FOR UPDATE" AFAICT return '' -class SQLiteSchemaGenerator(ansisql.ANSISchemaGenerator): + +class SQLiteSchemaGenerator(compiler.SchemaGenerator): def get_column_specification(self, column, **kwargs): colspec = self.preparer.format_column(column) + " " + column.type.dialect_impl(self.dialect).get_col_spec() @@ -391,12 +381,17 @@ class SQLiteSchemaGenerator(ansisql.ANSISchemaGenerator): # else: # super(SQLiteSchemaGenerator, self).visit_primary_key_constraint(constraint) -class SQLiteSchemaDropper(ansisql.ANSISchemaDropper): +class SQLiteSchemaDropper(compiler.SchemaDropper): pass -class SQLiteIdentifierPreparer(ansisql.ANSIIdentifierPreparer): +class SQLiteIdentifierPreparer(compiler.IdentifierPreparer): def __init__(self, dialect): super(SQLiteIdentifierPreparer, self).__init__(dialect, omit_schema=True) dialect = SQLiteDialect dialect.poolclass = pool.SingletonThreadPool +dialect.statement_compiler = SQLiteCompiler +dialect.schemagenerator = SQLiteSchemaGenerator +dialect.schemadropper = SQLiteSchemaDropper +dialect.preparer = SQLiteIdentifierPreparer + |