]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Added psycopg2cffi dialect
authorShaun Stanworth <shaun.stanworth@onefinestay.com>
Sun, 9 Nov 2014 14:52:31 +0000 (14:52 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 26 Jan 2015 23:43:19 +0000 (18:43 -0500)
lib/sqlalchemy/dialects/postgresql/__init__.py
lib/sqlalchemy/dialects/postgresql/psycopg2.py
lib/sqlalchemy/dialects/postgresql/psycopg2cffi.py [new file with mode: 0644]
setup.cfg
test/dialect/postgresql/test_dialect.py
test/dialect/postgresql/test_query.py
test/dialect/postgresql/test_types.py
test/engine/test_execute.py
test/requirements.py
test/sql/test_types.py

index 1cff8e3a07f3c9978ba8237898d8abecfaffacf8..01a84631427ac08cf4d3dd15281d5eda9718ed81 100644 (file)
@@ -5,7 +5,7 @@
 # This module is part of SQLAlchemy and is released under
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
-from . import base, psycopg2, pg8000, pypostgresql, zxjdbc
+from . import base, psycopg2, pg8000, pypostgresql, zxjdbc, psycopg2cffi
 
 base.dialect = psycopg2.dialect
 
index fe27da8b67adcea2e4aedc4eba849bd7d80e4172..5246abf1ccd1637236d71e3772ae59ad5a121876 100644 (file)
@@ -512,9 +512,19 @@ class PGDialect_psycopg2(PGDialect):
         import psycopg2
         return psycopg2
 
+    @classmethod
+    def _psycopg2_extensions(cls):
+        from psycopg2 import extensions
+        return extensions
+
+    @classmethod
+    def _psycopg2_extras(cls):
+        from psycopg2 import extras
+        return extras
+
     @util.memoized_property
     def _isolation_lookup(self):
-        from psycopg2 import extensions
+        extensions = self._psycopg2_extensions()
         return {
             'AUTOCOMMIT': extensions.ISOLATION_LEVEL_AUTOCOMMIT,
             'READ COMMITTED': extensions.ISOLATION_LEVEL_READ_COMMITTED,
@@ -536,7 +546,8 @@ class PGDialect_psycopg2(PGDialect):
         connection.set_isolation_level(level)
 
     def on_connect(self):
-        from psycopg2 import extras, extensions
+        extras = self._psycopg2_extras()
+        extensions = self._psycopg2_extensions()
 
         fns = []
         if self.client_encoding is not None:
@@ -586,7 +597,7 @@ class PGDialect_psycopg2(PGDialect):
     @util.memoized_instancemethod
     def _hstore_oids(self, conn):
         if self.psycopg2_version >= (2, 4):
-            from psycopg2 import extras
+            extras = self._psycopg2_extras()
             oids = extras.HstoreAdapter.get_oids(conn)
             if oids is not None and oids[0]:
                 return oids[0:2]
diff --git a/lib/sqlalchemy/dialects/postgresql/psycopg2cffi.py b/lib/sqlalchemy/dialects/postgresql/psycopg2cffi.py
new file mode 100644 (file)
index 0000000..5217c55
--- /dev/null
@@ -0,0 +1,46 @@
+# testing/engines.py
+# Copyright (C) 2005-2014 the SQLAlchemy authors and contributors
+# <see AUTHORS file>
+#
+# This module is part of SQLAlchemy and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+"""
+.. dialect:: postgresql+psycopg2cffi
+    :name: psycopg2cffi
+    :dbapi: psycopg2cffi
+    :connectstring: \
+postgresql+psycopg2cffi://user:password@host:port/dbname\
+[?key=value&key=value...]
+    :url: http://pypi.python.org/pypi/psycopg2cffi/
+
+`psycopg2cffi` is an adaptation of `psycopg2`, using CFFI for the C
+layer. This makes it suitable for use in e.g. PyPy. Documentation
+is as per `psycopg2`.
+
+.. seealso::
+
+    :mod:`sqlalchemy.dialects.postgresql.psycopg2`
+
+"""
+from .psycopg2 import PGDialect_psycopg2
+
+
+class PGDialect_psycopg2cffi(PGDialect_psycopg2):
+    driver = 'psycopg2cffi'
+
+    @classmethod
+    def dbapi(cls):
+        return __import__('psycopg2cffi')
+
+    @classmethod
+    def _psycopg2_extensions(cls):
+        root = __import__('psycopg2cffi', fromlist=['extensions'])
+        return root.extensions
+
+    @classmethod
+    def _psycopg2_extras(cls):
+        root = __import__('psycopg2cffi', fromlist=['extras'])
+        return root.extras
+
+
+dialect = PGDialect_psycopg2cffi
index 51a4e30bf259d1b064ec5baba8bcb038c6c3db38..5eb35469f923ec80983f65f7409b785c7735167b 100644 (file)
--- a/setup.cfg
+++ b/setup.cfg
@@ -42,6 +42,7 @@ postgresql=postgresql://scott:tiger@127.0.0.1:5432/test
 pg8000=postgresql+pg8000://scott:tiger@127.0.0.1:5432/test
 postgres=postgresql://scott:tiger@127.0.0.1:5432/test
 postgresql_jython=postgresql+zxjdbc://scott:tiger@127.0.0.1:5432/test
+postgresql_psycopg2cffi=postgresql+psycopg2cffi://127.0.0.1:5432/test
 mysql=mysql://scott:tiger@127.0.0.1:3306/test
 mysqlconnector=mysql+mysqlconnector://scott:tiger@127.0.0.1:3306/test
 mssql=mssql+pyodbc://scott:tiger@ms_2008
index b751bbcdd7e63636abbe05c6c8c1c29bc9928551..2166bca328dd71e9f9406fab050a0d55bc449896 100644 (file)
@@ -118,7 +118,7 @@ class MiscTest(fixtures.TestBase, AssertsExecutionResults, AssertsCompiledSQL):
         eq_(c.connection.connection.encoding, test_encoding)
 
     @testing.only_on(
-        ['postgresql+psycopg2', 'postgresql+pg8000'],
+        ['postgresql+psycopg2', 'postgresql+pg8000', 'postgresql+psycopg2cffi'],
         'psycopg2 / pg8000 - specific feature')
     @engines.close_open_connections
     def test_autocommit_isolation_level(self):
index 26ff5e93b1282adf15715859fc6720c73e280232..73319438d25e2cb3f5fa773ef3be822833fa988a 100644 (file)
@@ -729,6 +729,7 @@ class MatchTest(fixtures.TestBase, AssertsCompiledSQL):
     @testing.fails_on('postgresql+psycopg2', 'uses pyformat')
     @testing.fails_on('postgresql+pypostgresql', 'uses pyformat')
     @testing.fails_on('postgresql+zxjdbc', 'uses qmark')
+    @testing.fails_on('postgresql+psycopg2cffi', 'uses pyformat')
     def test_expression_positional(self):
         self.assert_compile(matchtable.c.title.match('somstr'),
                             'matchtable.title @@ to_tsquery(%s)')
index c62ca79a89ec6d78242c92417ec53417506881ff..5f1d37b24fa5f6093b52fc09dc80d82c789979ea 100644 (file)
@@ -379,10 +379,11 @@ class NumericInterpretationTest(fixtures.TestBase):
     __backend__ = True
 
     def test_numeric_codes(self):
-        from sqlalchemy.dialects.postgresql import pg8000, psycopg2, base
-
-        for dialect in (pg8000.dialect(), psycopg2.dialect()):
+        from sqlalchemy.dialects.postgresql import psycopg2cffi, pg8000, \
+            psycopg2, base
 
+        dialects = pg8000.dialect(), psycopg2.dialect(), psycopg2cffi.dialect()
+        for dialect in dialects:
             typ = Numeric().dialect_impl(dialect)
             for code in base._INT_TYPES + base._FLOAT_TYPES + \
                     base._DECIMAL_TYPES:
index 725dcebe062757210552c9e205b9a68c2f686c1e..b5b414af2417ae50fc0932b6c92cc5e2558e3cd1 100644 (file)
@@ -174,7 +174,7 @@ class ExecuteTest(fixtures.TestBase):
     @testing.skip_if(
         lambda: testing.against('mysql+mysqldb'), 'db-api flaky')
     @testing.fails_on_everything_except(
-        'postgresql+psycopg2',
+        'postgresql+psycopg2', 'postgresql+psycopg2cffi',
         'postgresql+pypostgresql', 'mysql+mysqlconnector',
         'mysql+pymysql', 'mysql+cymysql')
     def test_raw_python(self):
index ffbdfba23ef88b38e1cf7abbe09f68d2e7fb469c..6b8ba504c93e38f6950fb3dd90954791ed3b9722 100644 (file)
@@ -756,6 +756,10 @@ class DefaultRequirements(SuiteRequirements):
                     "+psycopg2", None, None,
                     "psycopg2 2.4 no longer accepts percent "
                     "sign in bind placeholders"),
+                (
+                    "+psycopg2cffi", None, None,
+                    "psycopg2cffi does not accept percent signs in "
+                    "bind placeholders"),
                 ("mysql", None, None, "executemany() doesn't work here")
             ]
         )
index 38b3ced13655f816d16ec9cb7f2865e6af9322c9..5e15428531995d9b75d1a875b69d701575ae940f 100644 (file)
@@ -952,6 +952,7 @@ class UnicodeTest(fixtures.TestBase):
             expected = (testing.db.name, testing.db.driver) in \
                 (
                     ('postgresql', 'psycopg2'),
+                    ('postgresql', 'psycopg2cffi'),
                     ('postgresql', 'pypostgresql'),
                     ('postgresql', 'pg8000'),
                     ('postgresql', 'zxjdbc'),