2015-12-29 65 views
1

App Engine的開發服務器documentation說以下內容:爲什麼App引擎返回錯誤的應用程序ID?

開發服務器模擬生產App Engine服務。其中一種方法是將一個字符串(dev~)預先加入APPLICATION_ID環境變量中。谷歌建議始終得到使用get_application_id


在我的應用程序的應用程序ID,我用不同的本地資源比我生產做。因此,我有,當我啓動App Engine的實例如下:

import logging 

from google.appengine.api.app_identity import app_identity 
# ... 
# other imports 
# ... 

DEV_IDENTIFIER = 'dev~' 
application_id = app_identity.get_application_id() 
is_development = DEV_IDENTIFIER in application_id 

logging.info("The application ID is '%s'") 
if is_development: 
    logging.warning("Using development configuration") 

    # ... 
    # set up application for development 
    # ... 

# ... 

然而,當我通過與dev_appserver.py app.yaml命令行啓動我的本地開發服務器,我得到了我的控制檯輸出如下:

INFO: The application ID is 'development-application' 
WARNING: Using development configuration 

顯然,文檔聲明的dev~標識符將被預先寫入我的應用程序標識中。我也嘗試使用App Engine Launcher UI來查看是否改變了任何內容,但沒有改變。

請注意'開發應用程序'是我的實際應用程序的名稱,但我期望它是'dev〜開發應用程序'。

回答

6

谷歌建議使用get_application_id

始終得到應用ID,但是,那是,如果你關心的應用程序ID - 你不這樣做:你所關心的分區。查看源代碼 - 發佈在https://code.google.com/p/googleappengine/source/browse/trunk/python/google/appengine/api/app_identity/app_identity.py

get_app_identity使用os.getenv('APPLICATION_ID')然後傳遞到其內部功能_ParseFullAppId - 其通過_PARTITION_SEPARATOR = '~'分割它(從而再次除去dev~前綴dev_appserver.py前置到環境變量)。這是作爲「分區」返回到get_app_identity(忽略它,只從嚴格意義上返回應用程序ID)。

不幸的是,沒有架構的方式來獲得分區(實際上你只關心分區)。

爲了區分您是在本地運行還是在「正在運行」(即在Google的服務器appspot.com上),爲了在每種情況下訪問不同的資源,您都會從中獲得靈感Google自己的例子就是這樣做的 - 具體來說,請查看app.py示例https://cloud.google.com/appengine/docs/python/cloud-sql/#Python_Using_a_local_MySQL_instance_during_development

在該示例中,重點是如果您在生產環境中運行,則訪問Cloud SQL實例,而如果您在本地運行,則訪問本地MySQL實例。但這是次要的 - 讓我們來關注一下,谷歌自己的例子是如何說明這種情況的?相關的代碼是...:

if (os.getenv('SERVER_SOFTWARE') and 
     os.getenv('SERVER_SOFTWARE').startswith('Google App Engine/')): 
     ...snipped: what to do if you're in production!... 
    else: 
     ...snipped: what to do if you're in the local server!... 

所以,這是我推薦你使用的測試。

那麼,作爲一名Python大師,我實際上有點尷尬,我的同事們正在使用這個略遜一籌的Python代碼(兩次調用os.getenv) - 我,我會按照如下代碼...:

in_prod = os.getenv('SERVER_SOFTWARE', '').startswith('Google App Engine/') 
if in_prod: 
    ...whatever you want to do if we're in production... 
else: 
    ...whatever you want to do if we're in the local server... 

,但是,這是完全一樣的語義,只是更優雅的Python表示(利用第二個可選參數os.getenv提供一個默認值)。

我會試圖讓這個小Python的改進成例如也把它放在你正在使用的文檔頁面(沒有任何理由只是需要找出如果他們的應用程序在督促中運行或者本地應該查看關於雲端SQL使用的文檔 - 所以,這個這是一個文檔,我們對此表示歉意)。但是,儘管我正在努力改進我們的文檔,但我希望這樣的回答足以讓您自信地進行。

+0

是否有直接鏈接到正在討論的源文檔的版本?我發現,當我需要理解一個概念時,我一直在看的這些文檔非常棒,但是當我需要做一些更復雜的事情時,很難追蹤源代碼。 – nmagerko

+2

所有的SDK資源都可以通過https://code.google.com/p/googleappengine/source/browse/#svn%2Ftrunk%2Fpython在線瀏覽,或者您也可以在https: //code.google.com/p/googleappengine/source/checkout以及其他許多方式。 –

2

該文檔似乎是錯誤的,當我在本地運行命令時,它只是從app.yaml中吐出名稱。

話雖這麼說,我們使用

import os 
os.getenv('SERVER_SOFTWARE', '').startswith('Dev') 

,以檢查它是否是開發應用程序服務器。

+0

剛剛運行了'os.getenv(「APPLICATION_ID」))'並且它返回了前綴爲'dev〜'的應用程序版本,所以這很有趣。 – miah

+0

我認爲他們是這樣寫的。正如他們所說的,'os.getenv(「APPLICATION_ID」))'不能保證產生適當的環境特定的應用程序ID,但是我上面使用的方法是。 – nmagerko

+1

@nmagerko,要點是,應用程序ID是* NOT *環境特定的 - 它總是你的app.yaml中的字符串;諸如'dev〜'的前綴被稱爲「分區」,並且不是應用程序ID的一部分。我同意這些文件在這些方面令人困惑,我正在努力改進它,正如我接受的答案一樣。 –

相關問題