]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
rowid_column becomes more like the "order by column". 'default_ordering' flag sent...
authorMike Bayer <mike_mp@zzzcomputing.com>
Sun, 1 Jan 2006 21:08:22 +0000 (21:08 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sun, 1 Jan 2006 21:08:22 +0000 (21:08 +0000)
still should better define 'default_ordering'/'rowid_column' relationship since its a little kludgy.

lib/sqlalchemy/databases/postgres.py
lib/sqlalchemy/engine.py
lib/sqlalchemy/mapping/mapper.py
lib/sqlalchemy/mapping/properties.py
lib/sqlalchemy/sql.py
test/mapper.py
test/testbase.py

index 3ae83cb8c4001e93b9075a5e54d8a7a178ec9307..e00d16d048a869ab91f5e776223f7831fa20fed2 100644 (file)
@@ -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
 
index f3cc8efada45f2ae4fdc67e4a1ec9815c7a93520..68cf08931528252200e530c55688201779638b6d 100644 (file)
@@ -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):
index f9b62b9f5a375e3fe78cf9b86e949886bd447f30..6af044fbbd41841c9b6bf95ff946d3bf36083f89 100644 (file)
@@ -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
         
index 6fb078d78e0a505734fea9855650cd8d0fdef6b8..d049aec9885426922054e3a2ca4bd4b3a10f6cf2 100644 (file)
@@ -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:
index 79af19cc01bef0d05b9082fe37612a844b4c22df..65246cdf22e3d15bbe9ef20e86d87aa42887de16 100644 (file)
@@ -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)
 
index 95ab4cb664d1554a4a7bb805bd3ce7877a41361e..2c5cfa7e2034243ae9613d483b308155393f27b3 100644 (file)
@@ -625,7 +625,7 @@ class EagerTest(MapperSuperTest):
         items = orderitems
         
         m = mapper(Item, items, properties = dict(
-                keywords = relation(Keyword, keywords, itemkeywords, lazy = False),
+                keywords = relation(Keyword, keywords, itemkeywords, lazy=False),
             ))
         l = m.select()
         self.assert_result(l, Item, *item_keyword_result)
index c1342a5fcb7ef60b85563828ae8c666a44a17efa..825d540fa471f9c970935ba7b207eecb63d8116a 100644 (file)
@@ -23,17 +23,17 @@ def parse_argv():
     global db
     if DBTYPE == 'sqlite':
         try:
-            db = engine.create_engine('sqlite://filename=:memory:', echo = echo)
+            db = engine.create_engine('sqlite://filename=:memory:', echo=echo, default_ordering=True)
         except:
             raise "Could not create sqlite engine.  specify --db <sqlite|sqlite_file|postgres|mysql|oracle> to test runner."
     elif DBTYPE == 'sqlite_file':
-        db = engine.create_engine('sqlite://filename=querytest.db', echo = echo)
+        db = engine.create_engine('sqlite://filename=querytest.db', echo=echo, default_ordering=True)
     elif DBTYPE == 'postgres':
-        db = engine.create_engine('postgres://database=test&host=127.0.0.1&user=scott&password=tiger', echo=echo)
+        db = engine.create_engine('postgres://database=test&host=127.0.0.1&user=scott&password=tiger', echo=echo, default_ordering=True)
     elif DBTYPE == 'mysql':
-        db = engine.create_engine('mysql://db=test&host=127.0.0.1&user=scott&passwd=tiger', echo=echo)
+        db = engine.create_engine('mysql://db=test&host=127.0.0.1&user=scott&passwd=tiger', echo=echo, default_ordering=True)
     elif DBTYPE == 'oracle':
-        db = engine.create_engine('oracle://user=scott&password=tiger', echo=echo)
+        db = engine.create_engine('oracle://user=scott&password=tiger', echo=echo, default_ordering=True)
     db = EngineAssert(db)
 
 class PersistTest(unittest.TestCase):