2

我正在尝试在更改组挂钩期间将一些构建请求排队在数据库中。DB 表由 Django 应用程序管理。所以,在钩子中,我想使用 Django 模型来提交构建请求。但是,我无法正确设置以成功导入模型。

基于此(https://docs.djangoproject.com/en/1.3/ref/django-admin/)信息,我需要做的就是将我的 django 站点添加到 sys 路径,并设置 DJANGO_SETTINGS_MODULE。django 站点位于 /opt/mysite 中,因此 - 从 python 控制台尝试:

>>> import sys
>>> import os
>>> sys.path.append('/opt')
>>> os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
>>> from mysite.myapp.models import Build
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/mysite/myapp/models.py", line 1, in <module>
    from django.db import models
  File "/usr/lib/pymodules/python2.7/django/db/__init__.py", line 78, in <module>
    connection = connections[DEFAULT_DB_ALIAS]
  File "/usr/lib/pymodules/python2.7/django/db/utils.py", line 93, in __getitem__
    backend = load_backend(db['ENGINE'])
  File "/usr/lib/pymodules/python2.7/django/db/utils.py", line 33, in load_backend
    return import_module('.base', backend_name)
  File "/usr/lib/pymodules/python2.7/django/utils/importlib.py", line 35, in import_module
    __import__(name)
  File "/usr/lib/pymodules/python2.7/django/db/backends/mysql/base.py", line 28, in <module>
    from django.db import utils
ImportError: cannot import name utils
>>>

第二次尝试:

基于此(http://www.b-list.org/weblog/2007/sep/22/standalone-django-scripts/)我可以使用setup_environ(),当我在python shell中尝试这个时,它可以工作:

>>> import sys
>>> sys.path.append('/opt')
>>> from django.core.management import setup_environ
>>> from mysite import settings
>>> setup_environ(settings)
'/opt/mysite'
>>> from mysite.myapp.models import Build
>>> Build.objects.all()
[<Build: #1 F nkj sdfsdfsdfs43qg test_branch>, <Build: #2 F nkj sdfsdfsdfs43qg test_branch>, <Build: #13 Q   >, <Build: #14 Q   nkj_bug243>, <Build: #11 F nkj 444hwe45hedrrt nkj_bug272>, <Build: #12 F nkj sdfsdfsdfs43qg test_branch>]

但是,当我在 Mercurial 钩子中尝试此操作时,在尝试导入构建模型的那一刻,我就被错误所困扰:

#!/usr/bin/env python
import sys
path = '/opt'
if path not in sys.path:
    sys.path.append(path)

from django.core.management import setup_environ
from mysite import settings
setup_environ(settings)

from mysite.myapp.models import Build
import datetime

... do stuff ...

当它到达'from mysite.myapp.models import Build'行时,我得到以下错误输出:

** unknown exception encountered, please report by visiting
**  http://mercurial.selenic.com/wiki/BugTracker
** Python 2.7.2+ (default, Oct  4 2011, 20:06:09) [GCC 4.6.1]
** Mercurial Distributed SCM (version 1.9.1)
** Extensions loaded:
Traceback (most recent call last):
  File "/usr/bin/hg", line 38, in <module>
    mercurial.dispatch.run()
  File "/usr/lib/python2.7/dist-packages/mercurial/dispatch.py", line 27, in run
    sys.exit(dispatch(request(sys.argv[1:])))
  File "/usr/lib/python2.7/dist-packages/mercurial/dispatch.py", line 64, in dispatch
    return _runcatch(req)
  File "/usr/lib/python2.7/dist-packages/mercurial/dispatch.py", line 87, in _runcatch
    return _dispatch(req)
  File "/usr/lib/python2.7/dist-packages/mercurial/dispatch.py", line 679, in _dispatch
    cmdpats, cmdoptions)
  File "/usr/lib/python2.7/dist-packages/mercurial/dispatch.py", line 454, in runcommand
    ret = _runcommand(ui, options, cmd, d)
  File "/usr/lib/python2.7/dist-packages/mercurial/dispatch.py", line 733, in _runcommand
    return checkargs()
  File "/usr/lib/python2.7/dist-packages/mercurial/dispatch.py", line 687, in checkargs
return cmdfunc()
  File "/usr/lib/python2.7/dist-packages/mercurial/dispatch.py", line 676, in <lambda>
    d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
  File "/usr/lib/python2.7/dist-packages/mercurial/util.py", line 385, in check
return func(*args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/mercurial/commands.py", line 3884, in push
    newbranch=opts.get('new_branch'))
  File "/usr/lib/python2.7/dist-packages/mercurial/localrepo.py", line 1428, in push
lock=lock)
  File "/usr/lib/python2.7/dist-packages/mercurial/localrepo.py", line 1849, in addchangegroup
source=srctype, url=url)
  File "/usr/lib/python2.7/dist-packages/mercurial/localrepo.py", line 224, in hook
    return hook.hook(self.ui, self, name, throw, **args)
  File "/usr/lib/python2.7/dist-packages/mercurial/hook.py", line 160, in hook
    mod = extensions.loadpath(path, 'hghook.%s' % hname)
  File "/usr/lib/python2.7/dist-packages/mercurial/extensions.py", line 45, in loadpath
    return imp.load_source(module_name, path)
  File "/opt/unapse/belvedere/mercurial_hook.py", line 14, in <module>
    from unapse.belvedere.models import Build
  File "/usr/lib/python2.7/dist-packages/mercurial/demandimport.py", line 109, in _demandimport
    mod = _origimport(name, globals, locals)
  File "/opt/unapse/belvedere/models.py", line 1, in <module>
    from django.db import models
  File "/usr/lib/python2.7/dist-packages/mercurial/demandimport.py", line 109, in _demandimport
    mod = _origimport(name, globals, locals)
  File "/usr/lib/pymodules/python2.7/django/db/__init__.py", line 14, in <module>
    if not settings.DATABASES:
  File "/usr/lib/pymodules/python2.7/django/utils/functional.py", line 276, in __getattr__
    self._setup()
  File "/usr/lib/pymodules/python2.7/django/conf/__init__.py", line 42, in _setup
    self._wrapped = Settings(settings_module)
  File "/usr/lib/pymodules/python2.7/django/conf/__init__.py", line 139, in __init__
    logging_config_func(self.LOGGING)
  File "/usr/lib/python2.7/logging/config.py", line 776, in dictConfig
    dictConfigClass(config).configure()
  File "/usr/lib/python2.7/logging/config.py", line 575, in configure
    '%r: %s' % (name, e))
ValueError: Unable to configure handler 'mail_admins': __import__() argument 1 must be string, not DictConfigurator

关于可能导致此问题的任何想法?

4

2 回答 2

1

DictConfigurator 错误是 python 中的一个错误,希望在下一个 2.7 版本(http://bugs.python.org/issue12718)中得到修复,某些东西(可能是 mercurial)正在覆盖导入,并且在这种情况下 python 的日志记录代码会失败。

在那之前,这是我为解决它所做的。将 dictconfig.py 从 django/utils 复制到你的 python 系统路径中的某个地方(我把它放在我的钩子旁边)。换行

importer = __import__

至:

def importer(self, *args):
    return __import(*args)__

然后在你的 django 项目的 settings.py 中添加到最后:

LOGGING_CONFIG = 'website.dictconfig.dictConfig'

将 website.dictconfig 更新为您将 dictconfig 文件放入的任何路径,以便 python 可以找到它。

更新:我认为有一个更简单的方法。在导入任何其他内容之前,将其添加到钩子脚本的顶部:

from mercurial import demandimport;
demandimport.disable()

这使得 Mercurial 恢复了导入覆盖,并且似乎干净地解决了问题。

于 2013-03-28T19:31:08.913 回答
0

If you're running with your environment in a virtualenv dir you'll need to add that to the site packages and I'd also suggest that you put the django dir at the front of sys.path instead of the end.

Here's the code we use to integrate our Django app into other python apps.

import os
import sys

# point this at the virtualenv dir that your django deployment runs out of
# you are using virtualenv. right?
DJANGO_ENV = '/home/core/python-envs/production'

# where your code lives (ie where settings.py is)
DJANGO_DIR = '/home/core/code/production'

# add our site packages
import site
site_packages = os.path.join(DJANGO_ENV, 'lib', 'python%s' % sys.version[:3], 'site-packages')
site.addsitedir(site_packages)

# put the main Django directory on first
sys.path.insert(0, DJANGO_DIR)

# setup the Django environment pointing to our settings
import settings
import django.core.management
django.core.management.setup_environ(settings)

# finally, import our objects
from yourapp.models import YourModel

One last thing to note is that when we import our code into some applications we've run into scoping issues and imports clashing. To get around it we wrap the work we want to do in a function so that it gets its own scope.

For example, instead of:

from yourapp.models import YourModel
objs = YourModel.objects.filter(something=True)
...

Do something like:

def do_work():
    from yourapp.models import YourModel
    objs = YourModel.objects.filter(something=True)
    ...
do_work()
于 2012-04-05T18:02:46.997 回答