python/django-extensions ImportError: Нет модуля с именем common.types_
Мне удалось запустить простой скрипт, расположенный в папке 'scripts', используя 'runcript' из django-extensions. Техника описана здесь [1] ( https://django-extensions.readthedocs.org/en/latest/runscript.html). Сценарий будет успешно выполняться следующим образом:
python manage.py runscript mysimplescript --script-args Testing 123
Если я сейчас переместлю скрипт в подпапку, то, похоже, мне нужно указать полный путь к подпапке:
python manage.py runscript scripts.myfolder.mysimplescript --script-args Testing 123
Я написал скрипт Python, который успешно запускается при вызове непосредственно из командной строки в своей папке проекта. Сложный сценарий использует ряд дополнительных сценариев, расположенных внутри множества подпапок.
Теперь я хочу вызвать этот скрипт в django, используя django-extensions 'runcript', что означает, что он вызывается из папки 'mysite /', где расположен manage.py. Сценарий "mycomplexscript.py" находится не в папке "scripts /", а перемещен в отдельную папку проекта "myapps /" вместе с подпапками и сценариями.
Ниже показана структура, которая включает в себя "mysite /" и некоторые подпапки / файлы в "myapp /", в частности модуль "myapp / common / types_":
mysite/
manage.py
mysite/
__init__.py
settings.py
urls.py
wsgi.py
scripts
__init__.py
mysimplescript.py
myapps/
__init__.py
mycomplexscript.py
common/
__init__.py
comparison.py
serialisation/
__init__.py
serialisation.py
xml.py
types_/
__init__.py
enum.py
Django-extensions требует, чтобы mycomplexscript.py включал функцию run(). Строка № 6 импортирует класс из одной из подпапок проекта:
def run(*script_args):
import os
import sys
import time
from common.serialisation import XML
При вызове сценария возникает ошибка, поскольку модуль 'common.types_' не может быть найден.
python manage.py runscript myapps.mycomplexscript --script-args Testing 123
/usr/lib/python2.7/site-packages/Django-1.9.2-py2.7.egg/django/core/
management/base.py:265: RemovedInDjango110Warning: OptionParser usage for
Django management commands is deprecated, use ArgumentParser instead
RemovedInDjango110Warning)
Exception while running run() in 'myapps.mycomplexscript'
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/usr/lib/python2.7/site-packages/Django-1.9.2-py2.7.egg/django/core/
management/__init__.py", line 353, in execute_from_command_line
utility.execute()
File "/usr/lib/python2.7/site-packages/Django-1.9.2-py2.7.egg/django/core/
management/__init__.py", line 345, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/lib/python2.7/site-packages/django_extensions-1.6.1-py2.7.egg/
django_extensions/management/email_notifications.py", line 63, in
run_from_argv
super(EmailNotificationCommand, self).run_from_argv(argv)
File "/usr/lib/python2.7/site-packages/Django-1.9.2-py2.7.egg/django/core/
management/base.py", line 348, in run_from_argv
self.execute(*args, **cmd_options)
File "/usr/lib/python2.7/site-packages/django_extensions-1.6.1-py2.7.egg/
django_extensions/management/email_notifications.py", line 75, in execute
super(EmailNotificationCommand, self).execute(*args, **options)
File "/usr/lib/python2.7/site-packages/Django-1.9.2-py2.7.egg/django/core/
management/base.py", line 399, in execute
output = self.handle(*args, **options)
File "/usr/lib/python2.7/site-packages/django_extensions-1.6.1-py2.7.egg/
django_extensions/management/utils.py", line 57, in inner
ret = func(self, *args, **kwargs)
File "/usr/lib/python2.7/site-packages/django_extensions-1.6.1-py2.7.egg/
django_extensions/management/commands/runscript.py", line 172, in handle
run_script(mod, *script_args)
File "/usr/lib/python2.7/site-packages/django_extensions-1.6.1-py2.7.egg/
django_extensions/management/commands/runscript.py", line 79, in run_script
mod.run(*script_args)
File "/usr/tester/SwFact/isg_cid-system_test_current/my_site/myapps/
mycomplexscript.py", line 9, in run
from myapps.common.serialisation import XML
File "/usr/tester/SwFact/isg_cid- system_test_current/my_site/myapps/
common/__init__.py", line 7, in <module>
from comparison import Comparison
File "/usr/tester/SwFact/isg_cid-system_test_current/my_site/myapps/
common/comparison.py", line 7, in <module>
from common.types_ import Enum
ImportError: No module named common.types_
Проблемная строка № 7 в файле "82.py "выглядит следующим образом:
from common.types_ import Enum
Ошибка может быть исправлена, если полный путь к корню проекта указан явно (+++):
from apps.common.types_ import Enum
Это означает, что мне нужно будет отредактировать все файлы и соответственно изменить пути, которых я бы хотел избежать, если это возможно. Эта ссылка [2]:( Python: ссылка на другой проект) описывает ссылку на другой проект из командной строки, поэтому я понимаю, что это может не иметь ничего общего с тем фактом, что я пытаюсь сделать это с помощью расширений django '' RunScript.
Есть ли способ, которым я могу устранить несоответствие пути, без необходимости изменять все файлы? Будет ли установка PYTHONPATH ответом, как предложено здесь [3]:( Как использовать PYTHONPATH)? Я проверил, но 'echo $PYTHONPATH' в настоящее время ничего не возвращает.
Извиняюсь за многословное описание.
Заранее спасибо.
1 ответ
Я попробовал sys.path.append("my/path"), как рекомендовано по ссылке выше и [4]:( Python sys.path - добавление PYTHONPATH), и это, похоже, работает, поэтому все пути, включенные в 'from', теперь распознается без указания полного пути, как я уже описывал здесь (+++).
myapps/mycomplexscript:
# Procedures
def run(*script_args):
import os
import sys
import time
sys.path.append('/usr/tester/SwFact/isg_cid-system_test_current/
my_site/myapps')
from common.serialisation import XML
from common.task import Subscriber
from test_ import TestHost
from common.filesystem import Directory, File
from common.tables import Column, Condition, CSVTable, Group
from string import Template
from datetime import date, time, datetime, timedelta
from operator import itemgetter
print script_args
Итак, результат при запуске скрипта из 'mysite/':
python manage.py runscript myapps.mycomplexscript --script-args Testing 123
/usr/lib/python2.7/site-packages/Django-1.9.2-py2.7.egg/django/core/
management/base.py:265: RemovedInDjango110Warning: OptionParser usage for
Django management commands is deprecated, use ArgumentParser instead
RemovedInDjango110Warning)
('Testing', '123')
Не идеально жестко кодировать путь внутри скрипта, поэтому, возможно, его можно будет передать в качестве одного из аргументов. Единственная проблема с этим заключается в том, что импорт появляется в верхней части файла, до того, как какой-либо аргумент командной строки будет обработан в сложном скрипте, однако, по крайней мере, я знаю, что он работает в принципе.