From 3b483dac2e9a58e83bdecbd2b2a0c6ed90cc4013 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sat, 2 Feb 2013 21:03:57 -0500 Subject: [PATCH] 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] --- doc/build/changelog/changelog_07.rst | 11 ++++++++ lib/sqlalchemy/dialects/mysql/gaerdbms.py | 33 +++++++++++++++++++---- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/doc/build/changelog/changelog_07.rst b/doc/build/changelog/changelog_07.rst index c747edb16..e23dc1f5e 100644 --- a/doc/build/changelog/changelog_07.rst +++ b/doc/build/changelog/changelog_07.rst @@ -8,6 +8,17 @@ :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 diff --git a/lib/sqlalchemy/dialects/mysql/gaerdbms.py b/lib/sqlalchemy/dialects/mysql/gaerdbms.py index 87493dd76..2203504f2 100644 --- a/lib/sqlalchemy/dialects/mysql/gaerdbms.py +++ b/lib/sqlalchemy/dialects/mysql/gaerdbms.py @@ -41,8 +41,20 @@ class MySQLDialect_gaerdbms(MySQLDialect_mysqldb): @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): @@ -50,12 +62,23 @@ class MySQLDialect_gaerdbms(MySQLDialect_mysqldb): 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 \ No newline at end of file +dialect = MySQLDialect_gaerdbms