如何正确地将 PyTZ 添加到 Google App Engine 应用程序?

Posted

技术标签:

【中文标题】如何正确地将 PyTZ 添加到 Google App Engine 应用程序?【英文标题】:How to properly add PyTZ to a Google App Engine application? 【发布时间】:2010-12-15 16:18:20 【问题描述】:

这有点尴尬,但是我一直没能找到关于这个话题的好资源。

我正在开发一个需要复杂时区转换的 Google App Engine 应用程序。由于我离强加的配额还差得很远,所以我选择了 PyTZ。但是,我一定做错了什么。到目前为止我所做的是:

    将 PyTZ 下载为 tarball 安装并复制pytz 目录进入我的应用程序的根目录 (它是webapp 的兄弟姐妹 app.yaml 所在的目录)。

但是,如果我尝试实例化时区,PyTZ 似乎永远找不到任何时区。这是来自 GAE 交互式控制台的示例会话:

from pytz import timezone

rome = timezone('Europe/Rome')

输出如下:

Traceback (most recent call last):
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/admin/__init__.py", line 210, in post
    exec(compiled_code, globals())
  File "<string>", line 3, in <module>
  File "/Library/Python/2.5/site-packages/pytz-2009j-py2.5.egg/pytz/__init__.py", line 157, in timezone
UnknownTimeZoneError: 'Europe/Rome'

我做错了什么?提前感谢您的帮助。

注意:如果我只是在本地使用 python 交互式 shell,事情会按预期工作:

>>> from pytz import datetime, timezone
>>> rome = timezone('Europe/Rome')
>>> rome.localize(datetime.datetime.now())
datetime.datetime(2009, 11, 12, 0, 4, 52, 990114, tzinfo=<DstTzInfo 'Europe/Rome' CET+1:00:00 STD>)

编辑:我需要澄清一下我没有使用压缩版本的 PyTZ。我已经在我的项目中包含了整个 zoneinfo 目录:

pc-morena:pytz lyudmilangelov$ cd zoneinfo/
pc-morena:zoneinfo lyudmilangelov$ ls -l
total 448
drwxr-xr-x@  55 lyudmilangelov  staff   1870 Nov 10 12:48 Africa
drwxr-xr-x@ 135 lyudmilangelov  staff   4590 Nov 10 12:48 America
drwxr-xr-x@  12 lyudmilangelov  staff    408 Nov 10 12:48 Antarctica
drwxr-xr-x@   3 lyudmilangelov  staff    102 Nov 10 12:48 Arctic
drwxr-xr-x@  93 lyudmilangelov  staff   3162 Nov 10 12:48 Asia
...

【问题讨论】:

【参考方案1】:

看起来您没有上传 pytz 的整个 zoneinfo 子树——在 22 个目录中的 570 个文件,在我手头的 pytz 版本中。不知道为什么——默认情况下,如果它们在您的应用程序目录中,它们应该被上传。触摸一些后尝试 appcfg.py --verbose update(甚至 --noisy)以检查它是否上传了它们

许多小文件在应用引擎中是个麻烦事,但要解决这个问题,需要对 init.py 中的 open_resource 函数进行一些调整,以使其从 zipfile 中获取“资源”,而不是尝试每个“资源”打开一个实际的单独文件。这个blog 提供了更多关于如何去做的细节(尤其有用的是 cmets 中的观察结果)。

【讨论】:

感谢您帮助我。然而,我认为这不是问题所在。我已经编辑了这个问题,以阐明我的项目目前的结构。【参考方案2】:

我想通了,这比我预期的要尴尬。

问题是(正如我在问题中指定的那样)我将 PyTZ 设为webapp兄弟。但是,为了让 GAE 能够加载它,它必须是 webappchild。这并不奇怪,但我预计 import pytz 会失败,如果这是问题所在。

无论如何,将 PyTZ 移动到 webapp 下可以解决问题,并且仍然可以从 webapp 的兄弟姐妹访问该模块(例如 test)。

【讨论】:

你还没有解释什么是'webapp'目录。它是你项目的根目录(包含 app.yaml 的那个)吗? 是的,webapp 是包含app.yaml 的目录。您指出这个问题具有误导性是对的。我已经对其进行了编辑以反映您指出的内容。如果有人愿意给出比我更有启发性的答案,我很乐意接受。【参考方案3】:

根据问题的标题,我想(但还没有那么好的声誉)投票赞成 jgeewax 的答案,因为这是我在搜索中找到这个问题时使用的。但是,我还要补充一点,在按照那里提到的说明进行操作后,我在 github 上创建了一个最小项目,该项目说明了在应用程序引擎中使用 pytz 和压缩的 zoneinfo 文件。可能会为某人节省 30 分钟的时间来在这里启动和运行实验:http://github.com/mpstx/appengine_py_pytz_zipimport_zoneinfo

【讨论】:

【参考方案4】:

另一种方法是使用包含进一步优化的 gae-pytz 打包版本: http://pypi.python.org/pypi/gaepytz

您只需要压缩存档中的 pytz 文件夹, 在您的 gae 项目中使用它非常简单:

from pytz.gae import pytz

【讨论】:

【参考方案5】:

为了解决这个问题,我采用了与gae-pytz 不同的方法,我创建了pytz-appengine。特别是 pytz-appengine 将所有时区信息放入 ndb 数据存储区。

pytz 的单元测试通过(至少只要它们通过上游)。 pytz-appengine 的主要动机是让按需更新时区数据库变得简单。有一个构建脚本 build.py 会自动执行此操作。

我欢迎任何反馈。

【讨论】:

【参考方案6】:

pytz 现在是一个built in GAE 库。可以直接导入。

【讨论】:

【参考方案7】:

我使用了此处的第 3 方说明:https://cloud.google.com/appengine/docs/standard/python/tools/using-libraries-python-27

只需 pip install pytz 进入 lib 目录,按照提示添加 appengine_config.py 文件和内容。

虽然 pytz 现在是 Google App Engine 库的一部分: https://cloud.google.com/appengine/docs/standard/python/tools/built-in-libraries-27 我无法让它工作。在 app.yaml 我添加了 - name: pytz 和 version: latest (也许版本应该是上面文档中列出的版本)。但它没有用。

【讨论】:

以上是关于如何正确地将 PyTZ 添加到 Google App Engine 应用程序?的主要内容,如果未能解决你的问题,请参考以下文章

如何正确地将多个片段添加到片段过渡?

如何正确地将安全区域插图添加到 UIStackView?

如何正确地将 UITextField 添加到 UITableViewCell

Google App Engine - Python 3 - ModuleNotFoundError:没有名为“pytz”的模块

如何正确地将 Kal 框架添加到我的 iPhone 项目中?

如何正确地将类型提示添加到 Mixin 类?