2013-01-08 42 views
3

從我的開發工作站使用SQLAlchemy 0.7.9連接到Google Cloud SQL時(希望使用create_all()生成模式),我一直不成功。我不能獲得通過以下錯誤:無法使用SQLAlchemy連接到來自開發服務器的Google Cloud SQL

sqlalchemy.exc.DBAPIError: (AssertionError) No api proxy found for service "rdbms" None None 

我能夠成功連接到使用google_sql.py instancename,最初開闢了瀏覽器對連接進行授權(現在出現的數據庫實例已緩存的授權雖然我沒有~/Library/Preferences/com.google.cloud.plist文件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() 

的FUL l stacktrace在這裏可用 - https://gist.github.com/4486641

回答

4

原來,mysql+gaerdbms:///司機在SQLAlchemy的只是安裝使用rdbms_apiproxy DBAPI,從谷歌應用程序引擎實例訪問谷歌雲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('...') URL作爲項目和實例現在提供的URL

mysql+gaerdbms:///<dbname>?instance=<project:instance> 

例如查詢字符串的一部分:

create_engine('mysql+gaerdbms:///mydb?instance=myproject:instance1') 
+0

你有沒有使用最新的SDK?我試着用SQLAlchemy 0.8.0發佈的方言和上面發佈的方言,並且仍然得到這裏描述的相同的錯誤:http://stackoverflow.com/questions/16192979/using-sqlalchemy-with-app-engine- and-google-cloud-sql-on-development-server – moraes

+0

我發現了一個解決方法,並更新了你的方言:http://stackoverflow.com/a/16198395/125967 – moraes

+1

對不起,通知評論和評論這個。當我使用本地mysql實例進行開發時,我是一個不同的連接字符串/驅動程序(只是默認的mysql://(mysql-python)驅動程序),並且在我的產品或ProductionDeploy配置中使用mysql + gaerdbms時, Flask-Script項目。我通常也不使用dev_appserver,而只使用標準的WSGI服務器。看起來像一個值得向上推進到SQLAlchemy的好改變。 –

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() 
+0

這個工作和我能夠'SELECT 1'運行。它經歷了像google_sql.py那樣的OAuth流程。 –

+0

我昨晚在現有的mysql + gaerdbms:/// dialect(http://goo.gl/WxpCV)上看了很多,它使用'from google.appengine.api import rdbms',它反過來使用'google.storage .speckle.python.api.rdbms_apiproxy'而不是巧妙的'google.storage.speckle.python.api.rdbms_googleapi',而不是像Django驅動程序那樣生產/ GAE實例(http://goo.gl/4ScgJ)。 –

+0

我試圖找到一種方法來更新mysql + gaerdbms:///方言來切換基於環境(如Django驅動程序)所使用的API('if apiproxy_stub_map.apiproxy.GetStub('rdbms'):「use rdbms_apiproxy「else」使用rdbms_googleapi「') –

相關問題