summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/databases/oracle.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2007-04-02 21:36:11 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2007-04-02 21:36:11 +0000
commitcdceb3c3714af707bfe3ede10af6536eaf529ca8 (patch)
tree2ccbfb60cd10d995c0309801b0adc4fc3a1f0a44 /lib/sqlalchemy/databases/oracle.py
parent8607de3159fd37923ae99118c499935c4a54d0e2 (diff)
downloadsqlalchemy-cdceb3c3714af707bfe3ede10af6536eaf529ca8.tar.gz
- merged the "execcontext" branch, refactors engine/dialect codepaths
- much more functionality moved into ExecutionContext, which impacted the API used by dialects to some degree - ResultProxy and subclasses now designed sanely - merged patch for #522, Unicode subclasses String directly, MSNVarchar implements for MS-SQL, removed MSUnicode. - String moves its "VARCHAR"/"TEXT" switchy thing into "get_search_list()" function, which VARCHAR and CHAR can override to not return TEXT in any case (didnt do the latter yet) - implements server side cursors for postgres, unit tests, #514 - includes overhaul of dbapi import strategy #480, all dbapi importing happens in dialect method "dbapi()", is only called inside of create_engine() for default and threadlocal strategies. Dialect subclasses have a datamember "dbapi" referencing the loaded module which may be None. - added "mock" engine strategy, doesnt require DBAPI module and gives you a "Connecition" which just sends all executes to a callable. can be used to create string output of create_all()/drop_all().
Diffstat (limited to 'lib/sqlalchemy/databases/oracle.py')
-rw-r--r--lib/sqlalchemy/databases/oracle.py75
1 files changed, 35 insertions, 40 deletions
diff --git a/lib/sqlalchemy/databases/oracle.py b/lib/sqlalchemy/databases/oracle.py
index adea127bf..5377759a2 100644
--- a/lib/sqlalchemy/databases/oracle.py
+++ b/lib/sqlalchemy/databases/oracle.py
@@ -8,15 +8,13 @@
import sys, StringIO, string, re
from sqlalchemy import util, sql, engine, schema, ansisql, exceptions, logging
-import sqlalchemy.engine.default as default
+from sqlalchemy.engine import default, base
import sqlalchemy.types as sqltypes
-try:
+def dbapi():
import cx_Oracle
-except:
- cx_Oracle = None
+ return cx_Oracle
-ORACLE_BINARY_TYPES = [getattr(cx_Oracle, k) for k in ["BFILE", "CLOB", "NCLOB", "BLOB", "LONG_BINARY", "LONG_STRING"] if hasattr(cx_Oracle, k)]
class OracleNumeric(sqltypes.Numeric):
def get_col_spec(self):
@@ -149,26 +147,32 @@ def descriptor():
]}
class OracleExecutionContext(default.DefaultExecutionContext):
- def pre_exec(self, engine, proxy, compiled, parameters):
- super(OracleExecutionContext, self).pre_exec(engine, proxy, compiled, parameters)
+ def pre_exec(self):
+ super(OracleExecutionContext, self).pre_exec()
if self.dialect.auto_setinputsizes:
- self.set_input_sizes(proxy(), parameters)
+ self.set_input_sizes()
+
+ def get_result_proxy(self):
+ if self.cursor.description is not None:
+ for column in self.cursor.description:
+ type_code = column[1]
+ if type_code in self.dialect.ORACLE_BINARY_TYPES:
+ return base.BufferedColumnResultProxy(self)
+
+ return base.ResultProxy(self)
class OracleDialect(ansisql.ANSIDialect):
- def __init__(self, use_ansi=True, auto_setinputsizes=True, module=None, threaded=True, **kwargs):
+ def __init__(self, use_ansi=True, auto_setinputsizes=True, threaded=True, **kwargs):
+ ansisql.ANSIDialect.__init__(self, default_paramstyle='named', **kwargs)
self.use_ansi = use_ansi
self.threaded = threaded
- if module is None:
- self.module = cx_Oracle
- else:
- self.module = module
- self.supports_timestamp = hasattr(self.module, 'TIMESTAMP' )
+ self.supports_timestamp = self.dbapi is None or hasattr(self.dbapi, 'TIMESTAMP' )
self.auto_setinputsizes = auto_setinputsizes
- ansisql.ANSIDialect.__init__(self, **kwargs)
-
- def dbapi(self):
- return self.module
-
+ if self.dbapi is not None:
+ self.ORACLE_BINARY_TYPES = [getattr(self.dbapi, k) for k in ["BFILE", "CLOB", "NCLOB", "BLOB", "LONG_BINARY", "LONG_STRING"] if hasattr(self.dbapi, k)]
+ else:
+ self.ORACLE_BINARY_TYPES = []
+
def create_connect_args(self, url):
if url.database:
# if we have a database, then we have a remote host
@@ -177,7 +181,7 @@ class OracleDialect(ansisql.ANSIDialect):
port = int(port)
else:
port = 1521
- dsn = self.module.makedsn(url.host,port,url.database)
+ dsn = self.dbapi.makedsn(url.host,port,url.database)
else:
# we have a local tnsname
dsn = url.host
@@ -206,20 +210,20 @@ class OracleDialect(ansisql.ANSIDialect):
else:
return "rowid"
- def create_execution_context(self):
- return OracleExecutionContext(self)
+ 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 schemagenerator(self, *args, **kwargs):
- return OracleSchemaGenerator(*args, **kwargs)
+ return OracleSchemaGenerator(self, *args, **kwargs)
def schemadropper(self, *args, **kwargs):
- return OracleSchemaDropper(*args, **kwargs)
+ return OracleSchemaDropper(self, *args, **kwargs)
- def defaultrunner(self, engine, proxy):
- return OracleDefaultRunner(engine, proxy)
+ 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':table_name.upper()})
@@ -405,15 +409,6 @@ class OracleDialect(ansisql.ANSIDialect):
if context is not None:
context._rowcount = rowcount
- def create_result_proxy_args(self, connection, cursor):
- args = super(OracleDialect, self).create_result_proxy_args(connection, cursor)
- if cursor and cursor.description:
- for column in cursor.description:
- type_code = column[1]
- if type_code in ORACLE_BINARY_TYPES:
- args['should_prefetch'] = True
- break
- return args
OracleDialect.logger = logging.class_logger(OracleDialect)
@@ -569,7 +564,7 @@ class OracleCompiler(ansisql.ANSICompiler):
class OracleSchemaGenerator(ansisql.ANSISchemaGenerator):
def get_column_specification(self, column, **kwargs):
colspec = self.preparer.format_column(column)
- colspec += " " + column.type.engine_impl(self.engine).get_col_spec()
+ colspec += " " + column.type.dialect_impl(self.dialect).get_col_spec()
default = self.get_column_default_string(column)
if default is not None:
colspec += " DEFAULT " + default
@@ -579,22 +574,22 @@ class OracleSchemaGenerator(ansisql.ANSISchemaGenerator):
return colspec
def visit_sequence(self, sequence):
- if not self.engine.dialect.has_sequence(self.connection, sequence.name):
+ if not self.dialect.has_sequence(self.connection, sequence.name):
self.append("CREATE SEQUENCE %s" % self.preparer.format_sequence(sequence))
self.execute()
class OracleSchemaDropper(ansisql.ANSISchemaDropper):
def visit_sequence(self, sequence):
- if self.engine.dialect.has_sequence(self.connection, sequence.name):
+ if self.dialect.has_sequence(self.connection, sequence.name):
self.append("DROP SEQUENCE %s" % sequence.name)
self.execute()
class OracleDefaultRunner(ansisql.ANSIDefaultRunner):
def exec_default_sql(self, default):
c = sql.select([default.arg], from_obj=["DUAL"], engine=self.engine).compile()
- return self.proxy(str(c), c.get_params()).fetchone()[0]
+ return self.connection.execute_compiled(c).scalar()
def visit_sequence(self, seq):
- return self.proxy("SELECT " + seq.name + ".nextval FROM DUAL").fetchone()[0]
+ return self.connection.execute_text("SELECT " + seq.name + ".nextval FROM DUAL").scalar()
dialect = OracleDialect