【问题标题】:Dynamically loading Python application code from database under Google App Engine在 Google App Engine 下从数据库中动态加载 Python 应用程序代码
【发布时间】:2011-03-31 03:22:09
【问题描述】:

我需要将 python 代码存储在数据库中,并将其加载到某种 bootstrap.py 应用程序中以供执行。我无法使用文件系统,因为我使用的是 GAE,所以这是我唯一的选择。

但是我不是一个有 python 经验的用户。

我已经能够加载 1 行代码并使用 eval 运行它,但是有两行或更多行的代码给了我一个“无效语法”错误。

我也在考虑是否可以扩展“导入”加载器来实现数据库加载。

谢谢!

【问题讨论】:

  • 我不知道这是否可能,但扩展导入听起来很有创意。
  • 如果 GAE 允许您覆盖 import,我会感到惊讶。为什么要在数据库中编写脚本代码?由于您声称没有使用 Python 的经验,因此可能有更好的方法来做您想做的事。你想完成什么。
  • 我正在尝试创建一个可以在不使用 GAE SDK 的情况下“自动”更新的应用程序。
  • 哦,自变形代码。多么可怕的想法。您看过 GAE 的应用程序版本控制吗?
  • 这不是重点。我想做一个非程序员可以使用和更新的应用程序。

标签: python google-app-engine google-cloud-datastore


【解决方案1】:

在阅读了有关 Python 动态代码加载的更多信息后,我能够做我想做的事。

这里是示例代码。我删除了标题以使其更轻:

还是谢谢!

=============

class DynCode(db.Model):
    name = db.StringProperty()
    code = db.TextProperty(default=None)

=============

class MainHandler(webapp.RequestHandler):
    def get(self):
        dyn = DynCode()
        dyn = "index"
        dyn.code = """
from google.appengine.ext import webapp
class MainHandler(webapp.RequestHandler):
    def get(self):
        self.response.out.write("Hello World\\n")
        self.response.out.write("Hello World 2\\n")
"""
        dyn.put()
        self.response.out.write("OK.")

def main():
    application = webapp.WSGIApplication([('/update', MainHandler)], debug=True)
    util.run_wsgi_app(application)

if __name__ == '__main__':
    main()

===================================

def main():
    query = DynCode.all()
    dyncodes = query.fetch(1)
    module = imp.new_module('mymodule')
    for dyn in dyncodes:
        exec dyn.code in module.__dict__

    application = webapp.WSGIApplication([('/', module.MainHandler)], debug=True)
    util.run_wsgi_app(application)

if __name__ == '__main__':
    main()

=========================

【讨论】:

  • 那么DynCode 是如何加载的呢? dyn.code 如何进行测试?如果dyn.code 出现语法错误,应用程序处于什么状态?
  • DynCode是上一个导入的简单文件。我将在一个单独的地方进行测试。从单独的文件加载语法损坏的代码或从字符串加载没有区别。
  • 非常有趣。 @HGF 3 年后你还在使用这个代码吗?我有兴趣做类似的事情。
  • 嗨@erasmospunk。该代码当时有效。我已经停止了这个项目,所以我不知道它是否仍然有效。
【解决方案2】:

如果你想要一个更健壮的机制,你可能想阅读PEP302,它描述了输入挂钩。您可以使用这些来导入代码,而不必对其进行评估。

【讨论】:

    【解决方案3】:

    我有点同意上面的评论,这听起来有点危险。然而:

    我用 App Engine 控制台 (http://con.appspot.com/console/) 做了一些实验,eval() 确实倾向于抛出 SyntaxError 的。

    相反,exec 语句可能是您的朋友 (http://docs.python.org/release/2.5.2/ref/exec.html)。

    我设法在 App Engine 控制台中运行了它:

    >>> exec "def f(x):\n    x = x + 1\n    y = 10\n    return x + y"
    >>> f(10)
    21
    

    所以试试exec 语句,但请记住直接来自最终用户的代码有很多很多(很多!)的危险。

    【讨论】:

    • 谢谢。我已经解决了我的问题。我想我在这个问题上被误解了。我的意图是使应用程序能够在需要时自行更新,而不是要求用户在安装后下载 GAE SDK 来更新应用程序。我将在这里发布我的实现。
    • 但是,您为什么认为这可能很危险?
    • 如果上面的代码来自最终用户,这将是危险的,它会使您的应用程序受到攻击和/或愚蠢。就算用户群控制得很严,你也永远不知道。
    • 好的。这是一个受控环境。 DB 中的代码只会被应用程序本身替换,并且可能会从单一的推力源下载。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-03
    • 2012-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多