【问题标题】:Python and YAML- GAE app settings filePython 和 YAML-GAE 应用程序设置文件
【发布时间】:2014-02-19 00:20:54
【问题描述】:

我正在阅读有关使用 YAML 在 GAE 应用程序中存储设置的信息,我想我想这样做。我说的是我自己的常量,比如 API 密钥和临时变量,而不是标准的 GAE 配置文件,比如 app.yaml。

到目前为止,我为它使用了一个简单的 settings.py 文件(其中包括用于生产/测试/等环境的单独配置),但它似乎做得不够好。

当 git merge 覆盖某些设置(难以控制)时,我什至遇到了一些严重的问题。

最终我想在数据存储中存储尽可能多的数据,但目前我正在寻找想法。

那么有人对简单存储和访问(有时是受保护的)配置数据有任何想法或示例吗?

【问题讨论】:

  • 我对自己的所有设置都使用了 settings.yaml 文件。我自己在那里没有遇到问题。我使用单独的部分进行测试,生产等......所以每个部分都是独立的。这样我就不会交换/移动 settings.yaml。
  • 我将 appengine_config 与:lib_config 用于默认值和挂钩:developers.google.com/appengine/docs/python/tools/…

标签: python google-app-engine yaml


【解决方案1】:

由于其他答案中列出的原因,您不应将配置值存储在源代码中。在我的最新项目中,我使用此类将配置数据放入数据存储区:

from google.appengine.ext import ndb

class Settings(ndb.Model):
  name = ndb.StringProperty()
  value = ndb.StringProperty()

  @staticmethod
  def get(name):
    NOT_SET_VALUE = "NOT SET"
    retval = Settings.query(Settings.name == name).get()
    if not retval:
      retval = Settings()
      retval.name = name
      retval.value = NOT_SET_VALUE
      retval.put()
    if retval.value == NOT_SET_VALUE:
      raise Exception(('Setting %s not found in the database. A placeholder ' +
        'record has been created. Go to the Developers Console for your app ' +
        'in App Engine, look up the Settings record with name=%s and enter ' +
        'its value in that record\'s value field.') % (name, name))
    return retval.value

您的应用程序会这样做以获得一个值:

AMAZON_KEY = Settings.get('AMAZON_KEY')

如果数据存储区中有该键的值,您将得到它。如果没有,将创建一个占位符记录并引发异常。异常会提醒您前往 Developers Console 并更新占位符记录。

我发现这消除了设置配置值的猜测。如果您不确定要设置哪些配置值,只需运行代码,它就会告诉您!

【讨论】:

    【解决方案2】:

    将 API 密钥和配置变量存储在静态文件中通常总是一个坏主意,原因如下:

    • 难以更新:您需要部署新应用才能更新值
    • 不安全:您可能会将其提交到版本控制系统并且无法返回
    • 不要扩展:很多时候,不同的域有不同的键

    那么为什么不从一开始就将所有这些值安全地存储在数据存储中,尤其是当它实际上非常容易时,方法如下:

    您所要做的就是为您的配置值创建一个新模型,并且其中只有一条记录。通过使用 NDB,您可以获得开箱即用的缓存,并且由于此配置文件的性质,您甚至可以在每个运行实例中缓存它,以避免对数据存储进行定期读取。

    class Config(ndb.Model):
      analytics_id = ndb.StringProperty(default='')
      brand_name = ndb.StringProperty(default='my-awesome-app')
      facebook_app_id = ndb.StringProperty(default='')
      facebook_app_secret = ndb.StringProperty(default='')
    
      @classmethod
      def get_master_db(cls):
        return cls.get_or_insert('master')
    

    我还猜测您已经有一个文件,很可能称为 config.py,其中您有一些像这些常量这样的常量:

    PRODUCTION = os.environ.get('SERVER_SOFTWARE', '').startswith('Google App Engine')
    DEVELOPMENT = not PRODUCTION
    

    如果您不创建一个,或者如果您只是将其添加到该文件中:

    import model   # Your module that contains the models
    
    CONFIG_DB = model.Config.get_master_db()
    

    最后为了能够读取您的配置值,您只需在应用中的任何位置执行此操作(当然是在导入 config.py 之后):

    config.CONFIG_DB.brand_name
    

    从现在开始,您甚至不必创建任何特殊的表单来更新这些值(但建议这样做),因为您可以从本地管理控制台或生产中的仪表板执行此操作。

    请记住,如果您要将记录存储在局部变量中,则必须在更新值后重新启动 instances 才能看到更改。


    您可以在我的一个名为gae-init 的开源项目中看到以上所有内容。

    【讨论】:

    • 这是一个不错的解决方案,但您如何保护自己不被错误地改变价值观?此外,如果您进行本地更改,是否必须手动从本地数据库复制更改?
    • @user2091046 错误地更改值?就像您保护自己不会以任何其他方式错误地更改它们一样。通过限制谁可以将这些值更改为最小值。对于本地值,您可以使用默认值或通过提供参数 @ 来启动开发服务器987654329@ 避免重置本地数据库..
    • 我必须以这种方式手动输入生产中的配置数据吗?我希望配置数据能够根据应用运行的环境(测试/产品)轻松切换
    • @user2091046 好吧.. 我建议您使用不同的测试和生产应用程序,而不是在同一件事上进行测试.. 因为您可能想要测试更危险的东西,并且通过使用单独的应用程序可以保护您免受破坏真实数据!
    • 这个解决方案有点工作,但我发现它很烦人:你仍然必须有一个路由来实例化类的一个实例,以便你可以在开发控制台中编辑该类的实体.那么,您似乎无法通过开发控制台编辑实体的键名,因此您无法真正知道它应该是什么。
    猜你喜欢
    • 2014-04-16
    • 2012-08-31
    • 2020-08-13
    • 2011-12-24
    • 2013-02-28
    • 2011-06-07
    • 2011-03-27
    • 2017-01-15
    • 2011-01-20
    相关资源
    最近更新 更多