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')

Не идеально жестко кодировать путь внутри скрипта, поэтому, возможно, его можно будет передать в качестве одного из аргументов. Единственная проблема с этим заключается в том, что импорт появляется в верхней части файла, до того, как какой-либо аргумент командной строки будет обработан в сложном скрипте, однако, по крайней мере, я знаю, что он работает в принципе.

Другие вопросы по тегам