Динамическая загрузка кода приложения Python из базы данных под Google App Engine - PullRequest
7 голосов
/ 17 августа 2010

Мне нужно сохранить код Python в базе данных и загрузить его в какое-нибудь приложение bootstrap.py для выполнения. Я не могу использовать файловую систему, потому что я использую GAE, так что это мой единственный выбор.

Однако я не опытный пользователь Python.

Я уже смог загрузить 1 строку кода и запустить ее с помощью eval, однако фрагмент кода с двумя или более строками дал мне ошибку «неверный синтаксис».

Я также думаю, возможно ли расширить загрузчик «import» для реализации загрузки БД.

Спасибо!

Ответы [ 3 ]

4 голосов
/ 17 августа 2010

Я смог сделать то, что хотел, прочитав больше о динамической загрузке кода 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()

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

2 голосов
/ 18 августа 2010

Если вам нужен более надежный механизм, вы, вероятно, захотите прочитать PEP302 , в котором описаны входные перехватчики. Вы можете использовать их для импорта кода, а не для его оценки.

2 голосов
/ 17 августа 2010

Я несколько согласен с комментаторами выше, это звучит довольно опасно. Тем не менее:

Я немного поэкспериментировал с консолью 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, но помните о многих, многих (многих!) Опасностях кода, поступающего непосредственно от конечных пользователей.

...