在Docker容器中运行Python脚本时出现导入错误?

3

我希望启动一个在容器内消费RabbitMQ消息的脚本,以下是重要细节:

messenger.py 是我尝试运行的脚本:

import pika
from . import create_app

class PikaMassenger():

    def __init__(self, *args, **kwargs):
        pass

    def consume(self, keys, callback):
        pass

    def __enter__(self):
        return self


    def __exit__(self, exc_type, exc_value, traceback):
        self.conn.close()



def start_consumer(app):

    def callback(ch, method, properties, body):
        try:
            print("Event recieved %r" % body)
            with app.app_context():
                pass

        except Exception as e:
            print("Consuming event %s failed: %s" % (method.routing_key, str(e)))

    with PikaMassenger() as consumer:
        consumer.consume(keys=['user.*', ], callback=callback)

if __name__ == "__main__":
    app = create_app()
    start_consumer(app)

我的__init__.py只包含应用程序工厂(create_app)。我的Dockerfile和docker-compose如下: Dockerfile:
FROM  python:3.6

COPY requirements.txt /app/requirements.txt

WORKDIR /app

RUN pip install -r requirements.txt

COPY . /app

ENV SECRET_KEY dev


ENV FLASK_APP run.py

CMD  flask run

docker-compose.yaml:

  app:
    build:
      context: ./app
    expose:
      - "5000"
      - PYTHONUNBUFFERED=1
    restart: on-failure

  app_consumer:
    build:
      context: ./app
    command: python -m messenger.py
    environment:
      - PYTHONUNBUFFERED=1
    restart: on-failure
    depends_on:
      - rabbitmq 

我想做的是使用相同的 Dockerfile 运行两个容器,并在其中一个中覆盖 command 参数,我知道基于上述细节,会出现错误:

 File "/app/massenger.py", line 2, in <module>
     from . import create_app
 ImportError: attempted relative import with no known parent package

也许我需要在docker-compose.yaml中更改工作目录,或以不同的方式运行我的脚本。
如果需要更多细节或者您想让我尝试一些东西,请告诉我。

无论 create_app 是什么,它都不在与 messenger.py 相同的目录中。如果它是通过 requirements.txt 安装的,只需直接导入即可。如果它是你编写的东西,那么你需要修复容器内脚本的路径。 - Dov Rine
1
这可能会有所帮助:https://napuzba.com/a/import-error-relative-no-parent - Dov Rine
肯定是在 init.py__ 文件中,我认为我在问题中已经表述得很清楚了。 - adnanmuttaleb
错误显示文件路径在 auth 目录下(/auth/massenger.py),请问根目录下是否有 auth 文件夹? - Soumen Mukherjee
这与应用程序相同,我仅为简化问题而将身份验证目录切换到应用程序。 - adnanmuttaleb
显示剩余5条评论
1个回答

1
我认为这个错误是由于路径中的 '.' 表示有误导致的。在本地环境中,'.' 代表当前目录。但是在 Docker 中,'.' 获取的是一些根目录的路径。
尝试将该路径作为静态路径给出,或使用 os.getcwd() 方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接