Mike Bayer  committed 3b688d4

engine argument on tables optional
test suite uses BaseProxyEngine as a base for the tester engine
documented global proxy engine

  • Participants
  • Parent commits 9dffcec

Comments (0)

Files changed (6)

 result set side.
 - postgres maintains a list of ANSI functions that must have no parenthesis so
 function calls with no arguments work consistently
+- tables can be created with no engine specified.  this will default their engine
+to a module-scoped "default engine" which is a ProxyEngine.  this engine can 
+be connected via the function "global_connect".
 - fixed a recursive call in schema that was somehow running 994 times then returning
 normally.  broke nothing, slowed down everything.  thanks to jpellerin for finding this.

File doc/build/content/dbengine.myt

         # now you have a real db connection and can select, insert, etc.
+    <&|doclib.myt:item, name="defaultproxy", description="Using the Global Proxy" &>
+    <p>There is an instance of ProxyEngine available within the schema package as "default_engine".  You can construct Table objects and not specify the engine parameter, and they will connect to this engine by default.  To connect the default_engine, use the <span class="codeline">global_connect</span> function.</p>
+    <&|formatting.myt:code&>
+    # define the tables and mappers
+    from sqlalchemy import *
+    # specify a table with no explicit engine
+    users = Table('users', 
+            Column('user_id', Integer, primary_key=True),
+            Column('user_name', String)
+        )
+    # connect the global proxy engine
+    global_connect('sqlite://filename=foo.db')
+    # create the table in the selected database
+    users.create()
+    </&>
+    </&>
     <&|doclib.myt:item, name="transactions", description="Transactions" &>
     <p>A SQLEngine also provides an interface to the transactional capabilities of the underlying DBAPI connection object, as well as the connection object itself.  Note that when using the object-relational-mapping package, described in a later section, basic transactional operation is handled for you automatically by its "Unit of Work" system;  the methods described here will usually apply just to literal SQL update/delete/insert operations or those performed via the SQL construction library.</p>

File lib/sqlalchemy/

 import sqlalchemy.schema
 import sqlalchemy.ext.proxy
 sqlalchemy.schema.default_engine = sqlalchemy.ext.proxy.ProxyEngine()
+def global_connect(*args, **kwargs):
+    sqlalchemy.schema.default_engine.connect(*args, **kwargs)

File lib/sqlalchemy/

     """a metaclass used by the Table object to provide singleton behavior."""
     def __call__(self, name, engine=None, *args, **kwargs):
+            if not isinstance(engine, SchemaEngine):
+                args = [engine] + list(args)
+                engine = None
             if engine is None:
                 engine = default_engine
             name = str(name)    # in case of incoming unicode

File test/

 import unittest
 import StringIO
 import sqlalchemy.engine as engine
-import sqlalchemy.ext.proxy
+import sqlalchemy.ext.proxy as proxy
+import sqlalchemy.schema as schema
 import re, sys
 echo = True
         raise "Could not create engine.  specify --db <sqlite|sqlite_file|postgres|mysql|oracle> to test runner."
     if PROXY:
-        db = sqlalchemy.ext.proxy.ProxyEngine(echo=echo, default_ordering=True)
+        db = proxy.ProxyEngine(echo=echo, default_ordering=True)
         db = engine.create_engine(db_uri, echo=echo, default_ordering=True)
             self.assert_(db.sql_count == count, "desired statement count %d does not match %d" % (count, db.sql_count))
-class EngineAssert(object):
+class EngineAssert(proxy.BaseProxyEngine):
     """decorates a SQLEngine object to match the incoming queries against a set of assertions."""
     def __init__(self, engine):
-        self.engine = engine
+        self._engine = engine
         self.realexec = engine.post_exec
         self.realexec.im_self.post_exec = self.post_exec
         self.logger = engine.logger
         self.set_assert_list(None, None)
         self.sql_count = 0
-    def __getattr__(self, key):
-        return getattr(self.engine, key)
+    def get_engine(self):
+        return self._engine
+    def set_engine(self, e):
+        self._engine = e
+#    def __getattr__(self, key):
+ #       return getattr(self.engine, key)
     def set_assert_list(self, unittest, list):
         self.unittest = unittest
         self.assert_list = list

File test/

                                    'float_column': 'float_column NUMERIC(25, 2)'
-        if not db.engine.__module__.endswith('sqlite'):
+        if not'sqlite':
             expectedResults['float_column'] = 'float_column FLOAT(25)'
         print db.engine.__module__