事实证明mysql+gaerdbms:///
,SQLAlchemy 中的驱动程序仅设置为使用rdbms_apiproxy
DBAPI,只能在从 Google App Engine 实例访问 Google Cloud SQL 时使用。我向 SQLAlchemy 提交了一张票以更新驱动程序,以便rdbms_googleapi
在不在 Google App Engine 上时使用基于 OAuth 的驱动程序,就像App Engine SDK 中提供的Django 驱动程序一样。rdbms_googleapi 也是使用的 DBAPI google_sql.py
(远程 sql 控制台)。
更新后的方言预计将成为 0.7.10 和 0.8.0 版本的一部分,但在它们可用之前,您可以执行以下操作:
1 - 将工单中更新的方言复制到文件(例如 gaerdbms_dialect.py)
from sqlalchemy.dialects.mysql.mysqldb import MySQLDialect_mysqldb
from sqlalchemy.pool import NullPool
import re
"""Support for Google Cloud SQL on Google App Engine
Connecting
-----------
Connect string format::
mysql+gaerdbms:///<dbname>?instance=<project:instance>
# Example:
create_engine('mysql+gaerdbms:///mydb?instance=myproject:instance1')
"""
class MySQLDialect_gaerdbms(MySQLDialect_mysqldb):
@classmethod
def dbapi(cls):
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):
# Cloud SQL connections die at any moment
return NullPool
def create_connect_args(self, url):
opts = url.translate_connect_args()
opts['dsn'] = '' # unused but required to pass to rdbms.connect()
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)
if code:
return int(code)
dialect = MySQLDialect_gaerdbms
2 - 注册自定义方言(您可以覆盖现有架构)
from sqlalchemy.dialects import registry
registry.register("mysql.gaerdbms", "application.database.gaerdbms_dialect", "MySQLDialect_gaerdbms")
注意: 0.8 允许在当前进程内注册方言(如上图)。如果您运行的是旧版本的 SQLAlchemy,我建议升级到 0.8+,否则您需要为此处概述的方言创建单独的安装。
3 - 更新您的create_engine('...')
url,因为项目和实例现在作为 URL 的查询字符串的一部分提供
mysql+gaerdbms:///<dbname>?instance=<project:instance>
例如:
create_engine('mysql+gaerdbms:///mydb?instance=myproject:instance1')