Skip to main content
 首页 » 编程设计

python之使用来自 mercurial python hook 的 Django 模型

2025年05月04日29cyq1162

我正在尝试在更改组 Hook 期间在数据库中排队一些构建请求。数据库表由 Django 应用程序管理。所以,在hook中,我想使用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 Hook 中尝试这个时,我在尝试导入我的构建模型的那一刻就遇到了错误:

#!/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 

关于可能导致此问题的原因有什么想法吗?

请您参考如下方法:

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

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

importer = __import__ 

到:

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

然后在您的 django 项目的 settings.py 中添加到末尾:

LOGGING_CONFIG = 'website.dictconfig.dictConfig' 

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

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

from mercurial import demandimport; 
demandimport.disable() 

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