Commits

Mike Bayer committed 4723ef0

Added a conditional import to the ``gaerdbms`` dialect which attempts
to import rdbms_apiproxy vs. rdbms_googleapi to work
on both dev and production platforms. Also now honors the
``instance`` attribute. Courtesy Sean Lynch. Also backported
enhancements to allow username/password as well as
fixing error code interpretation from 0.8.
[ticket:2649]

  • Participants
  • Parent commits 5e8dc03
  • Branches rel_0_7

Comments (0)

Files changed (2)

doc/build/changelog/changelog_07.rst

     :version: 0.7.10
     :released:
 
+    .. change:
+        :tags: sql, mysql, gae
+        :tickets: 2649
+
+        Added a conditional import to the ``gaerdbms`` dialect which attempts
+        to import rdbms_apiproxy vs. rdbms_googleapi to work
+        on both dev and production platforms.  Also now honors the
+        ``instance`` attribute.  Courtesy Sean Lynch.  Also backported
+        enhancements to allow username/password as well as
+        fixing error code interpretation from 0.8.
+
     .. change::
         :tags: sql, bug
         :tickets: 2594, 2584

lib/sqlalchemy/dialects/mysql/gaerdbms.py

 
     @classmethod
     def dbapi(cls):
-        from google.appengine.api import rdbms
-        return rdbms
+        # from django:
+        # http://code.google.com/p/googleappengine/source/
+        #     browse/trunk/python/google/storage/speckle/
+        #     python/django/backend/base.py#118
+        # see also [ticket:2649]
+        # see also http://stackoverflow.com/q/14224679/34549
+        from google.appengine.api import apiproxy_stub_map
+
+        if apiproxy_stub_map.apiproxy.GetStub('rdbms'):
+            from google.storage.speckle.python.api import rdbms_apiproxy
+            return rdbms_apiproxy
+        else:
+            from google.storage.speckle.python.api import rdbms_googleapi
+            return rdbms_googleapi
 
     @classmethod
     def get_pool_class(cls, url):
         return NullPool
 
     def create_connect_args(self, url):
-        return [[],{'database':url.database}]
+        opts = url.translate_connect_args()
+        # 'dsn' and 'instance' are because we are skipping
+        # the traditional google.api.rdbms wrapper
+
+        opts['dsn'] = ''
+        opts['instance'] = url.query['instance']
+        return [], opts
 
     def _extract_error_code(self, exception):
         match = re.compile(r"^(\d+):").match(str(exception))
-        code = match.group(1)
+        # The rdbms api will wrap then re-raise some types of errors
+        # making this regex return no matches.
+        if match:
+            code = match.group(1)
+        else:
+            code = None
         if code:
             return int(code)
 
-dialect = MySQLDialect_gaerdbms
+dialect = MySQLDialect_gaerdbms