python - 在 Django 站点的 pex 上调用 runserver 时如何解决 NotADirectoryError?
问题描述
我正在构建一个Django 站点的pex 包,如下所示:
$ pipenv-pex --entry-point "manage.main"
结果project.pex
按预期运行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
(似乎是__main__
在 pex 文件中找到方法?)以及如何正确调用它?
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是一个演示/开发网络服务器,可自动重新加载 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
BASE_DIR
您可以通过更新计算方式来解决这些问题settings.py
:
# 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)
通常,该进程认为它在常规文件夹中运行,但事实并非如此。可能需要进一步的解决方法。
推荐阅读
- flutter - 如何使用 GeoFire 插件在后台更新我的位置
- webrtc - 丢包问题中的 WebRTC 音频质量
- css - CSS网格设置跨度独立于轨道位置(网格列)
- go - 为什么这两个大浮点值不相等?
- kubernetes - Kubernetes 中的这个用户“系统:不安全”是什么?
- typescript - 使用所需的键和字符串索引记录
- node.js - 有没有一种简单的方法可以在节点模块中加载 json?
- mercure - Mercure Hub 服务器负载 - 更好的解决方案
- java - 为什么 else if 和 else 在这里表现不同?
- c# - Unity 无法从“字符串”转换为“整数”