]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- sql round trips are coming on line for sqlite, pg8000
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 30 Jan 2009 19:22:43 +0000 (19:22 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 30 Jan 2009 19:22:43 +0000 (19:22 +0000)
- pg8000 returns col.description as bytes, heh
- absolute module imports play havoc with "python test/foo/test.py" - start using -m

README.unittests
lib/sqlalchemy/dialects/postgres/base.py
lib/sqlalchemy/dialects/sqlite/pysqlite.py
lib/sqlalchemy/engine/base.py
lib/sqlalchemy/engine/default.py
lib/sqlalchemy/pool.py
test/testenv.py

index 4698494234b7db566b15831028947f1a99fe02a3..bb1ac3253bff8c0ffa1065fc75374c3b318dc414 100644 (file)
@@ -26,30 +26,39 @@ sys.path.  This forces the local version of SQLAlchemy to be used, bypassing
 any setuptools-installed installations (setuptools places .egg files ahead of
 plain directories, even if on PYTHONPATH, unfortunately).
 
+NEW INSTRUCTIONS FOR ABSOLUTE MODULE IMPORTS
+--------------------------------------------
+Py3K imports modules absolutely.  This means the old way of running unittests,
+such as "python test/sql/query.py", can break things badly.  How ?   By name
+conflicts in our test suite.  We have a unit test called "test/sql/select.py".
+The pg8000 DBAPI uses the Python "select" module.   If you run a script
+called "test/sql/query.py", now "test/sql" is part of the import path, and 
+pg8000 pulls in "test/sql/select.py" instead.   Kaboom !  So we run
+the tests using -m now.
 
 RUNNING ALL TESTS
 -----------------
 To run all tests:
 
-    $ python test/alltests.py
+    $ python -m alltests
 
 
 RUNNING INDIVIDUAL TESTS
 -------------------------
 Any unittest module can be run directly from the module file:
 
-    python test/orm/mapper.py
+    python -m orm.mapper
 
 To run a specific test within the module, specify it as ClassName.methodname:
 
-    python test/orm/mapper.py MapperTest.testget
+    python -m orm.mapper MapperTest.testget
 
 
 COMMAND LINE OPTIONS
 --------------------
 Help is available via --help
 
-    $ python test/alltests.py --help
+    $ python -m alltests --help
 
     usage: alltests.py [options] [tests...]
 
@@ -78,7 +87,7 @@ preexisting tables will interfere with the tests
 If you'll be running the tests frequently, database aliases can save a lot of
 typing.  The --dbs option lists the built-in aliases and their matching URLs:
 
-    $ python test/alltests.py --dbs
+    $ python -m alltests --dbs
     Available --db options (use --dburi to override)
                mysql    mysql://scott:tiger@127.0.0.1:3306/test
               oracle    oracle://scott:tiger@127.0.0.1:1521
@@ -87,7 +96,7 @@ typing.  The --dbs option lists the built-in aliases and their matching URLs:
 
 To run tests against an aliased database:
 
-    $ python test/alltests.py --db=postgres
+    $ python -m alltests --db=postgres
 
 To customize the URLs with your own users or hostnames, make a simple .ini
 file called `test.cfg` at the top level of the SQLAlchemy source distribution
@@ -106,7 +115,7 @@ SQLAlchemy logs its activity and debugging through Python's logging package.
 Any log target can be directed to the console with command line options, such
 as:
 
-    $ python test/orm/unitofwork.py --log-info=sqlalchemy.orm.mapper \
+    $ python -m orm.unitofwork --log-info=sqlalchemy.orm.mapper \
       --log-debug=sqlalchemy.pool --log-info=sqlalchemy.engine
 
 This would log mapper configuration, connection pool checkouts, and SQL
@@ -125,7 +134,8 @@ After the suite has been run with --coverage, an annotated version of any
 source file can be generated, marking statements that are executed with > and
 statements that are missed with !, by running the coverage.py utility with the
 "-a" (annotate) option, such as:
-
+    
+    # TODO: need to adjust this for -m flag
     $ python ./test/testlib/coverage.py -a ./lib/sqlalchemy/sql.py
 
 This will create a new annotated file ./lib/sqlalchemy/sql.py,cover. Pretty
index 0f514e3f4f2202ce682a35ff53d40fee63e65533..5221df5494c4268e99f9e47ffb99b80f6e822dad 100644 (file)
@@ -337,7 +337,11 @@ class PGDefaultRunner(base.DefaultRunner):
                     exc = "select nextval('\"%s\".\"%s_%s_seq\"')" % (sch, column.table.name, column.name)
                 else:
                     exc = "select nextval('\"%s_%s_seq\"')" % (column.table.name, column.name)
-                return self.execute_string(exc.encode(self.dialect.encoding))
+
+                if self.dialect.supports_unicode_statements:
+                    return self.execute_string(exc)
+                else:
+                    return self.execute_string(exc.encode(self.dialect.encoding))
 
         return super(PGDefaultRunner, self).get_column_default(column)
 
@@ -500,8 +504,11 @@ class PGDialect(default.DefaultDialect):
         if table.schema is not None:
             schema_where_clause = "n.nspname = :schema"
             schemaname = table.schema
+            
+            # Py2K
             if isinstance(schemaname, str):
                 schemaname = schemaname.decode(self.encoding)
+            # end Py2K
         else:
             schema_where_clause = "pg_catalog.pg_table_is_visible(c.oid)"
             schemaname = None
@@ -526,8 +533,10 @@ class PGDialect(default.DefaultDialect):
 
         s = sql.text(SQL_COLS, bindparams=[sql.bindparam('table_name', type_=sqltypes.Unicode), sql.bindparam('schema', type_=sqltypes.Unicode)], typemap={'attname':sqltypes.Unicode, 'default':sqltypes.Unicode})
         tablename = table.name
+        # Py2K
         if isinstance(tablename, str):
             tablename = tablename.decode(self.encoding)
+        # end Py2K
         c = connection.execute(s, table_name=tablename, schema=schemaname)
         rows = c.fetchall()
 
index 9183bfbe89d16690e391fb71a0a3fc5fbc567b28..9ccbd627079a635d35dfd4013c53c0b236238a63 100644 (file)
@@ -121,6 +121,7 @@ class SQLite_pysqlite(SQLiteDialect):
     default_paramstyle = 'qmark'
     poolclass = pool.SingletonThreadPool
     execution_ctx_cls = SQLite_pysqliteExecutionContext
+    description_encoding = None
     driver = 'pysqlite'
     
     def __init__(self, **kwargs):
index e0ade2c8d36d642abd96139e5b4382506850acc6..6944a52624a2f96012d577911ef64e4ae0fec01a 100644 (file)
@@ -1485,10 +1485,8 @@ class ResultProxy(object):
         for i, item in enumerate(metadata):
             colname = item[0]
 
-            # Py2K
             if self.dialect.description_encoding:
                 colname = colname.decode(self.dialect.description_encoding)
-            # end Py2K
             
             if '.' in colname:
                 # sqlite will in some circumstances prepend table name to colnames, so strip
index 42608b8ac4c646d77426ee328a98afc0559e5295..b136622704d3421e34ae26f4fcdbaec70d748f00 100644 (file)
@@ -31,8 +31,14 @@ class DefaultDialect(base.Dialect):
     supports_alter = True
     supports_sequences = False
     sequences_optional = False
+    
+    # Py3K
+    #supports_unicode_statements = True
+    #supports_unicode_binds = True
+    # Py2K
     supports_unicode_statements = False
     supports_unicode_binds = False
+    # end Py2K
     
     name = 'default'
     max_identifier_length = 9999
@@ -67,7 +73,13 @@ class DefaultDialect(base.Dialect):
         if label_length and label_length > self.max_identifier_length:
             raise exc.ArgumentError("Label length of %d is greater than this dialect's maximum identifier length of %d" % (label_length, self.max_identifier_length))
         self.label_length = label_length
-        self.description_encoding = getattr(self, 'description_encoding', encoding)
+        
+        if not hasattr(self, 'description_encoding'):
+            self.description_encoding = getattr(self, 'description_encoding', encoding)
+        
+        # Py3K
+        #self.supports_unicode_statements = True
+        #self.supports_unicode_binds = True
     
     @classmethod
     def type_descriptor(cls, typeobj):
index dabc2929eeb55082171f432f4315ea4373317cac..2d4e223c45f8fe966b1b25cb680e198ceb58a35d 100644 (file)
@@ -19,7 +19,7 @@ SQLAlchemy connection pool.
 import weakref, time, threading
 
 from sqlalchemy import exc, log
-from sqlalchemy import queue as Queue
+from sqlalchemy import queue as sqla_queue
 from sqlalchemy.util import thread, threading, pickle, as_interface
 
 proxies = {}
@@ -593,7 +593,7 @@ class QueuePool(Pool):
 
         """
         Pool.__init__(self, creator, **params)
-        self._pool = Queue.Queue(pool_size)
+        self._pool = sqla_queue.Queue(pool_size)
         self._overflow = 0 - pool_size
         self._max_overflow = max_overflow
         self._timeout = timeout
@@ -606,7 +606,7 @@ class QueuePool(Pool):
     def do_return_conn(self, conn):
         try:
             self._pool.put(conn, False)
-        except Queue.Full:
+        except sqla_queue.Full:
             if self._overflow_lock is None:
                 self._overflow -= 1
             else:
@@ -620,7 +620,7 @@ class QueuePool(Pool):
         try:
             wait = self._max_overflow > -1 and self._overflow >= self._max_overflow
             return self._pool.get(wait, self._timeout)
-        except Queue.Empty:
+        except sqla_queue.Empty:
             if self._max_overflow > -1 and self._overflow >= self._max_overflow:
                 if not wait:
                     return self.do_get()
@@ -648,7 +648,7 @@ class QueuePool(Pool):
             try:
                 conn = self._pool.get(False)
                 conn.close()
-            except Queue.Empty:
+            except sqla_queue.Empty:
                 break
 
         self._overflow = 0 - self.size()
index 808a3c5f0e9c676e59182f301a22618b66eac302..1cf6617c37814cb5428654e68ee9b56dbfe9272a 100644 (file)
@@ -20,8 +20,8 @@ def configure_for_tests():
         sys.path.insert(0, os.path.join(os.getcwd(), 'lib'))
         logging.basicConfig()
 
-        testlib.config.configure()
         _setup = True
+        testlib.config.configure()
 
 def simple_setup():
     """import testenv; testenv.simple_setup()"""