我使用SQLAlchemy 0.7.9从我的开发工作站连接到Google Cloud SQL失败了(希望使用create_all()生成模式)。我无法通过以下错误:
sqlalchemy.exc.DBAPIError: (AssertionError) No api proxy found for service "rdbms" None None
我能够使用google_sql.py instancename
成功连接到数据库实例,~/Library/Preferences/com.google.cloud.plist
最初打开了一个浏览器来授权连接(现在似乎已经缓存了授权,尽管我没有{{} 1}}文件https://developers.google.com/cloud-sql/docs/commandline表示我应该)
以下是我用来测试连接的简单应用程序:
from sqlalchemy import create_engine
engine = create_engine('mysql+gaerdbms:///myapp', connect_args={"instance":"test"})
connection = engine.connect()
此处提供完整的堆栈跟踪 - https://gist.github.com/4486641
答案 0 :(得分:4)
事实证明,SQLAlchemy中的mysql+gaerdbms:///
驱动程序仅设置为使用rdbms_apiproxy
DBAPI,只能在从Google App Engine实例访问Google Cloud SQL时使用。我向SQLAlchemy提交了ticket以更新驱动程序,以便在不在Google App Engine上时使用基于OAuth的rdbms_googleapi
,就像App Engine SDK中提供的Django driver一样。 rdbms_googleapi也是google_sql.py
使用的DBAPI(远程sql控制台)。
更新的方言预计将成为0.7.10和0.8.0版本的一部分,但在它们可用之前,您可以执行以下操作:
1 - 将ticket中更新的方言复制到文件中(例如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+,或者您需要按照here概述为方言创建单独的安装。
3 - 更新您的create_engine('...')
网址,因为项目和实例现已作为网址的查询字符串的一部分提供
mysql+gaerdbms:///<dbname>?instance=<project:instance>
例如:
create_engine('mysql+gaerdbms:///mydb?instance=myproject:instance1')
答案 1 :(得分:3)
我想我的工作示例脚本如下。你可以尝试类似的事情让我知道它是怎么回事吗?
但是(您可能已经意识到了这一点),如果您的目标是在Google Cloud SQL实例上创建架构,也许您可以针对本地mysql服务器创建架构,使用mysqldump转储它,然后导入架构到Google Cloud SQL。无论如何,使用本地mysql服务器非常方便开发。
from sqlalchemy import create_engine
from google.storage.speckle.python.api import rdbms as dbi_driver
from google.storage.speckle.python.api import rdbms_googleapi
INSTANCE = 'YOURPROJECT:YOURINSTANCE'
DATABASE = 'YOURDATABASE'
def get_connection():
return rdbms_googleapi.connect('', instance=INSTANCE, database=DATABASE)
def main():
engine = create_engine(
'mysql:///YOURPROJECT:YOURINSTANCE/YOURDATABASE',
module=dbi_driver,
creator=get_connection,
)
print engine.execute('SELECT 1').scalar()
if __name__ == '__main__':
main()