【问题标题】:What is a good place to store configuration in Google AppEngine (python)在Google AppEngine(python)中存储配置的好地方是什么
【发布时间】:2011-04-16 04:43:00
【问题描述】:

我正在制作一个 Google AppEngine 应用程序,但我怀疑我是否应该存储(敏感)配置数据,如凭据。

我应该创建一个单一的 bigtable 实体进行配置,还是有其他建议的方式来存储它。

【问题讨论】:

  • @systempuntoout 例如我用于访问 S3 的 Amazon AWS 凭证
  • 如果您不喜欢源代码中的普通凭据,唯一的方法是在数据存储上使用配置模型,否则您可以将设置存储在使用 @987654321 访问它的某个 .ini 文件中@.

标签: python google-app-engine configuration-files


【解决方案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 并更新占位符记录。

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

【讨论】:

  • 干得好,很有魅力,我还加了一个set方法!!
【解决方案2】:

如果您可以将它们嵌入到源中,您可以这样做,但如果您需要它可以动态配置,那么数据存储区就是您的最佳选择。您可以通过将它们缓存在本地内存中来避免获取每个请求的设置。这是一个帮助类:

class Configuration(db.Model):
  _INSTANCE = None

  @classmethod
  def get_instance(cls):
    if not cls._INSTANCE:
      cls._INSTANCE = cls.get_or_insert('config')
    return cls._INSTANCE

只需使用您需要的任何配置值对其进行子类化(或修改类本身)。由于加载的代码在请求之间持续存在,因此您只需为每个应用实例执行一次提取 - 尽管如果您希望能够动态更新配置,您可能需要构建超时。

如果您想在有限的时间内缓存内容,最好的选择是在获取时存储时间戳:

class Configuration(db.Model):
  CACHE_TIME = datetime.timedelta(minutes=5)

  _INSTANCE = None
  _INSTANCE_AGE = None

  @classmethod
  def get_instance(cls):
    now = datetime.datetime.now()
    if not cls._INSTANCE or cls._INSTANCE_AGE + cls.CACHE_TIME < now:
      cls._INSTANCE = cls.get_or_insert('config')
      cls._INSTANCE_AGE = now
    return cls._INSTANCE

【讨论】:

  • 非常有趣,我以前从未见过这种技术。通常我会使用 memcache 来最小化从数据存储中获取的次数,但只要加载实例,这看起来会更快。有什么内存限制可以防止过多使用吗?
  • 是的,有内存限制 - 尽管它们可能会发生变化。您可能不应该将实例内存用于通用缓存,但它是配置数据的理想选择。
  • 好的,谢谢,我会记住这一点。您对如何建立您所说的超时有任何指示吗?
  • @Nick 在这里看到一个快速而肮脏的超时会很酷。我第一次看到这种方法。
  • @Franck @systempuntoout 通过演示更新了答案。
【解决方案3】:

将它们存储在一个模块中。你可以很简单,比如有一个config.py 模块,比如:

AMAZON_KEY = 'XXXX'

然后使用:

import config
service = my_amazon_service(config.AMAZON_KEY)

或者有一个稍微复杂的配置对象,允许您为您的应用、命名空间配置键等设置合理的默认值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-12
    • 2018-09-15
    • 2011-02-22
    • 1970-01-01
    • 1970-01-01
    • 2015-07-16
    • 2012-01-29
    • 1970-01-01
    相关资源
    最近更新 更多