在 Django 站点的 pex 上调用 runserver 时如何解决 NotADirectoryError?
How can I resolve NotADirectoryError when calling runserver on pex of a Django site?
我正在构建一个 pex bundle Django 站点,如下所示:
$ pipenv-pex --entry-point "manage.main"
结果 project.pex
运行s 符合 runserver --help
的预期:
$ ./project.pex runserver --help
usage: toptal_joglog.pex runserver [-h] [--ipv6] [--nothreading] [--noreload]
[--nostatic] [--insecure] [--version]
[-v {0,1,2,3}] [--settings SETTINGS]
...
但是如果我尝试 运行 服务器,我会得到一个 NotADirectoryError(下面的回溯)。 execute_from_command_line
正在寻找什么目录(似乎是在 pex 文件中找到 __main__
方法?)以及如何正确调用它?
Watching for file changes with StatReloader
Performing system checks...
Traceback (most recent call last):
File "/home/user/Documents/project/project.pex/.bootstrap/pex/pex.py", line 396, in execute
File "/home/user/Documents/project/project.pex/.bootstrap/pex/pex.py", line 328, in _wrap_coverage
File "/home/user/Documents/project/project.pex/.bootstrap/pex/pex.py", line 359, in _wrap_profiling
File "/home/user/Documents/project/project.pex/.bootstrap/pex/pex.py", line 447, in _execute
File "/home/user/Documents/project/project.pex/.bootstrap/pex/pex.py", line 544, in execute_entry
File "/home/user/Documents/project/project.pex/.bootstrap/pex/pex.py", line 559, in execute_pkg_resources
File "/home/user/Documents/project/project.pex/manage.py", line 18, in main
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/core/management/__init__.py", line 401, in execute_from_command_line
utility.execute()
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/core/management/__init__.py", line 395, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/core/management/base.py", line 328, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/core/management/commands/runserver.py", line 60, in execute
super().execute(*args, **options)
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/core/management/base.py", line 369, in execute
output = self.handle(*args, **options)
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/core/management/commands/runserver.py", line 95, in handle
self.run(**options)
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/core/management/commands/runserver.py", line 102, in run
autoreload.run_with_reloader(self.inner_run, **options)
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/utils/autoreload.py", line 599, in run_with_reloader
start_django(reloader, main_func, *args, **kwargs)
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/utils/autoreload.py", line 584, in start_django
reloader.run(django_main_thread)
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/utils/autoreload.py", line 299, in run
self.run_loop()
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/utils/autoreload.py", line 305, in run_loop
next(ticker)
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/utils/autoreload.py", line 345, in tick
for filepath, mtime in self.snapshot_files():
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/utils/autoreload.py", line 361, in snapshot_files
for file in self.watched_files():
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/utils/autoreload.py", line 260, in watched_files
yield from iter_all_python_module_files()
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/utils/autoreload.py", line 105, in iter_all_python_module_files
return iter_modules_and_files(modules, frozenset(_error_files))
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/utils/autoreload.py", line 141, in iter_modules_and_files
resolved_path = path.resolve(strict=True).absolute()
File "/usr/lib/python3.7/pathlib.py", line 1161, in resolve
s = self._flavour.resolve(self, strict=strict)
File "/usr/lib/python3.7/pathlib.py", line 361, in resolve
return _resolve(base, str(path)) or sep
File "/usr/lib/python3.7/pathlib.py", line 345, in _resolve
target = accessor.readlink(newpath)
File "/usr/lib/python3.7/pathlib.py", line 443, in readlink
return os.readlink(path)
NotADirectoryError: [Errno 20] Not a directory: '/home/user/Documents/project/project.pex/__main__.py'
runserver 是一个 demo/development 网络服务器,可以自动重新加载 Python 代码。它的一项功能是重新加载 Python 代码,这样您就可以进行更改而无需重新启动本地开发实例。此功能在设计时并未真正考虑到 pex 文件布局的上下文。
您可以通过禁用重新加载功能来解决此问题:
./project.pex runserver --noreload
..在这一点上你可能会 运行 加载相对于 BASE_DIR
:
的文件
System check identified no issues (0 silenced).
Traceback (most recent call last):
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/db/backends/base/base.py", line 220, in ensure_connection
self.connect()
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/db/backends/base/base.py", line 197, in connect
self.connection = self.get_new_connection(conn_params)
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/db/backends/sqlite3/base.py", line 199, in get_new_connection
conn = Database.connect(**conn_params)
sqlite3.OperationalError: unable to open database file
您可以通过更新 settings.py
中 BASE_DIR
的计算方式来解决这些问题:
# when running from source
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# when running from pex
while os.path.isfile(BASE_DIR):
BASE_DIR = os.path.dirname(BASE_DIR)
一般情况下,该进程认为它 运行ning 在常规文件夹中,但事实并非如此。可能需要进一步的解决方法。
我正在构建一个 pex bundle Django 站点,如下所示:
$ pipenv-pex --entry-point "manage.main"
结果 project.pex
运行s 符合 runserver --help
的预期:
$ ./project.pex runserver --help
usage: toptal_joglog.pex runserver [-h] [--ipv6] [--nothreading] [--noreload]
[--nostatic] [--insecure] [--version]
[-v {0,1,2,3}] [--settings SETTINGS]
...
但是如果我尝试 运行 服务器,我会得到一个 NotADirectoryError(下面的回溯)。 execute_from_command_line
正在寻找什么目录(似乎是在 pex 文件中找到 __main__
方法?)以及如何正确调用它?
Watching for file changes with StatReloader
Performing system checks...
Traceback (most recent call last):
File "/home/user/Documents/project/project.pex/.bootstrap/pex/pex.py", line 396, in execute
File "/home/user/Documents/project/project.pex/.bootstrap/pex/pex.py", line 328, in _wrap_coverage
File "/home/user/Documents/project/project.pex/.bootstrap/pex/pex.py", line 359, in _wrap_profiling
File "/home/user/Documents/project/project.pex/.bootstrap/pex/pex.py", line 447, in _execute
File "/home/user/Documents/project/project.pex/.bootstrap/pex/pex.py", line 544, in execute_entry
File "/home/user/Documents/project/project.pex/.bootstrap/pex/pex.py", line 559, in execute_pkg_resources
File "/home/user/Documents/project/project.pex/manage.py", line 18, in main
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/core/management/__init__.py", line 401, in execute_from_command_line
utility.execute()
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/core/management/__init__.py", line 395, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/core/management/base.py", line 328, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/core/management/commands/runserver.py", line 60, in execute
super().execute(*args, **options)
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/core/management/base.py", line 369, in execute
output = self.handle(*args, **options)
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/core/management/commands/runserver.py", line 95, in handle
self.run(**options)
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/core/management/commands/runserver.py", line 102, in run
autoreload.run_with_reloader(self.inner_run, **options)
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/utils/autoreload.py", line 599, in run_with_reloader
start_django(reloader, main_func, *args, **kwargs)
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/utils/autoreload.py", line 584, in start_django
reloader.run(django_main_thread)
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/utils/autoreload.py", line 299, in run
self.run_loop()
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/utils/autoreload.py", line 305, in run_loop
next(ticker)
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/utils/autoreload.py", line 345, in tick
for filepath, mtime in self.snapshot_files():
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/utils/autoreload.py", line 361, in snapshot_files
for file in self.watched_files():
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/utils/autoreload.py", line 260, in watched_files
yield from iter_all_python_module_files()
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/utils/autoreload.py", line 105, in iter_all_python_module_files
return iter_modules_and_files(modules, frozenset(_error_files))
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/utils/autoreload.py", line 141, in iter_modules_and_files
resolved_path = path.resolve(strict=True).absolute()
File "/usr/lib/python3.7/pathlib.py", line 1161, in resolve
s = self._flavour.resolve(self, strict=strict)
File "/usr/lib/python3.7/pathlib.py", line 361, in resolve
return _resolve(base, str(path)) or sep
File "/usr/lib/python3.7/pathlib.py", line 345, in _resolve
target = accessor.readlink(newpath)
File "/usr/lib/python3.7/pathlib.py", line 443, in readlink
return os.readlink(path)
NotADirectoryError: [Errno 20] Not a directory: '/home/user/Documents/project/project.pex/__main__.py'
runserver 是一个 demo/development 网络服务器,可以自动重新加载 Python 代码。它的一项功能是重新加载 Python 代码,这样您就可以进行更改而无需重新启动本地开发实例。此功能在设计时并未真正考虑到 pex 文件布局的上下文。
您可以通过禁用重新加载功能来解决此问题:
./project.pex runserver --noreload
..在这一点上你可能会 运行 加载相对于 BASE_DIR
:
System check identified no issues (0 silenced).
Traceback (most recent call last):
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/db/backends/base/base.py", line 220, in ensure_connection
self.connect()
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/db/backends/base/base.py", line 197, in connect
self.connection = self.get_new_connection(conn_params)
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
File "/home/user/.pex/installed_wheels/76e2a7db05161ac57adcee837113974bb4f07b41/Django-3.0.6-py3-none-any.whl/django/db/backends/sqlite3/base.py", line 199, in get_new_connection
conn = Database.connect(**conn_params)
sqlite3.OperationalError: unable to open database file
您可以通过更新 settings.py
中 BASE_DIR
的计算方式来解决这些问题:
# when running from source
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# when running from pex
while os.path.isfile(BASE_DIR):
BASE_DIR = os.path.dirname(BASE_DIR)
一般情况下,该进程认为它 运行ning 在常规文件夹中,但事实并非如此。可能需要进一步的解决方法。