summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/databases
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2007-08-18 21:37:48 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2007-08-18 21:37:48 +0000
commit7c6c1b99c2de00829b6f34ffba7e3bb689d34198 (patch)
treeacd6f8dc84cea86fc58b195a5f1068cbe020e955 /lib/sqlalchemy/databases
parent534cf5fdbd05e2049ab9feceabf3926a5ab6380c (diff)
downloadsqlalchemy-7c6c1b99c2de00829b6f34ffba7e3bb689d34198.tar.gz
1. Module layout. sql.py and related move into a package called "sql".
2. compiler names changed to be less verbose, unused classes removed. 3. Methods on Dialect which return compilers, schema generators, identifier preparers have changed to direct class references, typically on the Dialect class itself or optionally as attributes on an individual Dialect instance if conditional behavior is needed. This takes away the need for Dialect subclasses to know how to instantiate these objects, and also reduces method overhead by one call for each one. 4. as a result of 3., some internal signatures have changed for things like compiler() (now statement_compiler()), preparer(), etc., mostly in that the dialect needs to be passed explicitly as the first argument (since they are just class references now). The compiler() method on Engine and Connection is now also named statement_compiler(), but as before does not take the dialect as an argument. 5. changed _process_row function on RowProxy to be a class reference, cuts out 50K method calls from insertspeed.py
Diffstat (limited to 'lib/sqlalchemy/databases')
-rw-r--r--lib/sqlalchemy/databases/access.py8
-rw-r--r--lib/sqlalchemy/databases/firebird.py42
-rw-r--r--lib/sqlalchemy/databases/informix.py41
-rw-r--r--lib/sqlalchemy/databases/mssql.py46
-rw-r--r--lib/sqlalchemy/databases/mysql.py36
-rw-r--r--lib/sqlalchemy/databases/oracle.py56
-rw-r--r--lib/sqlalchemy/databases/postgres.py48
-rw-r--r--lib/sqlalchemy/databases/sqlite.py41
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
+