summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2006-01-01 21:08:22 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2006-01-01 21:08:22 +0000
commit705f308452b0741747c27ee4edcd75f2ec0e6ae8 (patch)
tree9f23719ca0098f8d5a933aefc86a8abe32509f80 /lib/sqlalchemy
parent943bb0b0e08fec9bc0ccc784a4dd154783031e8d (diff)
downloadsqlalchemy-705f308452b0741747c27ee4edcd75f2ec0e6ae8.tar.gz
rowid_column becomes more like the "order by column". 'default_ordering' flag sent to create_engine enables whether or not the rowid_column on a Table will be None or not. mappers/relations will by default use the rowid_column for ordering if its not None, else theres no default ordering.
still should better define 'default_ordering'/'rowid_column' relationship since its a little kludgy.
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r--lib/sqlalchemy/databases/postgres.py30
-rw-r--r--lib/sqlalchemy/engine.py5
-rw-r--r--lib/sqlalchemy/mapping/mapper.py10
-rw-r--r--lib/sqlalchemy/mapping/properties.py6
-rw-r--r--lib/sqlalchemy/sql.py23
5 files changed, 49 insertions, 25 deletions
diff --git a/lib/sqlalchemy/databases/postgres.py b/lib/sqlalchemy/databases/postgres.py
index 3ae83cb8c..e00d16d04 100644
--- a/lib/sqlalchemy/databases/postgres.py
+++ b/lib/sqlalchemy/databases/postgres.py
@@ -106,7 +106,8 @@ def descriptor():
]}
class PGSQLEngine(ansisql.ANSISQLEngine):
- def __init__(self, opts, module = None, **params):
+ def __init__(self, opts, module=None, use_oids=False, **params):
+ self.use_oids = use_oids
if module is None:
if psycopg is None:
raise "Couldnt locate psycopg1 or psycopg2: specify postgres module argument"
@@ -153,20 +154,28 @@ class PGSQLEngine(ansisql.ANSISQLEngine):
def last_inserted_ids(self):
return self.context.last_inserted_ids
+ def rowid_column_name(self):
+ if self.use_oids:
+ return "oid"
+ else:
+ return None
+
def pre_exec(self, proxy, statement, parameters, **kwargs):
return
def post_exec(self, proxy, compiled, parameters, **kwargs):
if getattr(compiled, "isinsert", False) and self.context.last_inserted_ids is None:
- raise "cant use cursor.lastrowid without OIDs enabled"
- table = compiled.statement.table
- cursor = proxy()
- if cursor.lastrowid is not None and table is not None and len(table.primary_key):
- s = sql.select(table.primary_key, table.rowid_column == cursor.lastrowid)
- c = s.compile()
- cursor = proxy(str(c), c.get_params())
- row = cursor.fetchone()
- self.context.last_inserted_ids = [v for v in row]
+ if not self.use_oids:
+ raise "cant use cursor.lastrowid without OIDs enabled"
+ else:
+ table = compiled.statement.table
+ cursor = proxy()
+ if cursor.lastrowid is not None and table is not None and len(table.primary_key):
+ s = sql.select(table.primary_key, table.rowid_column == cursor.lastrowid)
+ c = s.compile()
+ cursor = proxy(str(c), c.get_params())
+ row = cursor.fetchone()
+ self.context.last_inserted_ids = [v for v in row]
def _executemany(self, c, statement, parameters):
"""we need accurate rowcounts for updates, inserts and deletes. psycopg2 is not nice enough
@@ -177,7 +186,6 @@ class PGSQLEngine(ansisql.ANSISQLEngine):
rowcount += c.rowcount
self.context.rowcount = rowcount
-
def dbapi(self):
return self.module
diff --git a/lib/sqlalchemy/engine.py b/lib/sqlalchemy/engine.py
index f3cc8efad..68cf08931 100644
--- a/lib/sqlalchemy/engine.py
+++ b/lib/sqlalchemy/engine.py
@@ -161,7 +161,7 @@ class SQLEngine(schema.SchemaEngine):
SQLEngines are constructed via the create_engine() function inside this package.
"""
- def __init__(self, pool = None, echo = False, logger = None, **params):
+ def __init__(self, pool=None, echo=False, logger=None, default_ordering=False, **params):
"""constructs a new SQLEngine. SQLEngines should be constructed via the create_engine()
function which will construct the appropriate subclass of SQLEngine."""
# get a handle on the connection pool via the connect arguments
@@ -172,6 +172,7 @@ class SQLEngine(schema.SchemaEngine):
self._pool = sqlalchemy.pool.manage(self.dbapi(), **params).get_pool(*cargs, **cparams)
else:
self._pool = pool
+ self.default_ordering=default_ordering
self.echo = echo
self.context = util.ThreadLocal(raiseerror=False)
self.tables = {}
@@ -258,7 +259,7 @@ class SQLEngine(schema.SchemaEngine):
raise NotImplementedError()
def rowid_column_name(self):
- """returns the ROWID column name for this engine."""
+ """returns the ROWID column name for this engine, or None if the engine cant/wont support OID/ROWID."""
return "oid"
def supports_sane_rowcount(self):
diff --git a/lib/sqlalchemy/mapping/mapper.py b/lib/sqlalchemy/mapping/mapper.py
index f9b62b9f5..6af044fbb 100644
--- a/lib/sqlalchemy/mapping/mapper.py
+++ b/lib/sqlalchemy/mapping/mapper.py
@@ -603,7 +603,7 @@ class Mapper(object):
if self.order_by:
order_by = self.order_by
elif self.table.rowid_column is not None:
- order_by = self.table.rowid_column
+ order_by = [self.table.rowid_column]
else:
order_by = None
else:
@@ -611,7 +611,7 @@ class Mapper(object):
if self._should_nest(**kwargs):
s2 = sql.select(self.table.primary_key, whereclause, use_labels=True, **kwargs)
- if not kwargs.get('distinct', False):
+ if not kwargs.get('distinct', False) and self.table.rowid_column is not None:
s2.order_by(self.table.rowid_column)
s3 = s2.alias('rowcount')
crit = []
@@ -621,17 +621,17 @@ class Mapper(object):
if kwargs.has_key('order_by'):
statement.order_by(*kwargs['order_by'])
else:
- statement.order_by(order_by)
+ statement.order_by(*order_by)
else:
statement = sql.select([], whereclause, from_obj=[self.table], use_labels=True, **kwargs)
if order_by is not None and kwargs.get('order_by', None) is None:
- statement.order_by(order_by)
+ statement.order_by(*order_by)
# for a DISTINCT query, you need the columns explicitly specified in order
# to use it in "order_by" - in the case we added the rowid column in,
# add that to the column list
# TODO: this idea should be handled by the SELECT statement itself, insuring
# that order_by cols are in the select list if DISTINCT is selected
- if kwargs.get('distinct', False) and order_by is self.table.rowid_column:
+ if kwargs.get('distinct', False) and self.table.rowid_column is not None and order_by == [self.table.rowid_column]:
statement.append_column(self.table.rowid_column)
# plugin point
diff --git a/lib/sqlalchemy/mapping/properties.py b/lib/sqlalchemy/mapping/properties.py
index 6fb078d78..d049aec98 100644
--- a/lib/sqlalchemy/mapping/properties.py
+++ b/lib/sqlalchemy/mapping/properties.py
@@ -592,7 +592,7 @@ class LazyLoader(PropertyLoader):
if allparams:
if self.order_by is not None:
order_by = self.order_by
- elif self.secondary is not None:
+ elif self.secondary is not None and self.secondary.rowid_column is not None:
order_by = [self.secondary.rowid_column]
else:
order_by = None
@@ -714,11 +714,11 @@ class EagerLoader(PropertyLoader):
if self.secondaryjoin is not None:
statement._outerjoin = sql.outerjoin(towrap, self.secondary, self.primaryjoin).outerjoin(self.eagertarget, self.eagersecondary)
- if self.order_by is None:
+ if self.order_by is None and self.secondary.rowid_column is not None:
statement.order_by(self.secondary.rowid_column)
else:
statement._outerjoin = towrap.outerjoin(self.eagertarget, self.eagerprimary)
- if self.order_by is None:
+ if self.order_by is None and self.eagertarget.rowid_column is not None:
statement.order_by(self.eagertarget.rowid_column)
if self.eager_order_by is not None:
diff --git a/lib/sqlalchemy/sql.py b/lib/sqlalchemy/sql.py
index 79af19cc0..65246cdf2 100644
--- a/lib/sqlalchemy/sql.py
+++ b/lib/sqlalchemy/sql.py
@@ -904,10 +904,25 @@ class TableImpl(FromClause):
def __init__(self, table):
self.table = table
self.id = self.table.name
- self._rowid_column = schema.Column(self.table.engine.rowid_column_name(), sqltypes.Integer, hidden=True)
- self._rowid_column._set_parent(table)
-
- rowid_column = property(lambda s: s._rowid_column)
+
+ def _rowid_col(self):
+ if not self.table.engine.default_ordering:
+ return None
+
+ if not hasattr(self, '_rowid_column'):
+ if self.table.engine.rowid_column_name() is not None:
+ self._rowid_column = schema.Column(self.table.engine.rowid_column_name(), sqltypes.Integer, hidden=True)
+ self._rowid_column._set_parent(self.table)
+ else:
+ if len(self.table.primary_key) > 0:
+ c = self.table.primary_key[0]
+ else:
+ c = self.table.columns[self.table.columns.keys()[0]]
+ self._rowid_column = schema.Column(c.name, c.type, hidden=True)
+ self._rowid_column._set_parent(self.table)
+ return self._rowid_column
+
+ rowid_column = property(_rowid_col)
engine = property(lambda s: s.table.engine)
columns = property(lambda self: self.table.columns)