【问题标题】:How to send a post request with postman while also saving to a Mongo database?如何使用邮递员发送发布请求,同时保存到 Mongo 数据库?
【发布时间】:2020-06-13 20:35:27
【问题描述】:

我正在制作一个虚构的角色生成器 API。当我在本地运行时通过 Postman 发送请求时运行良好,但通过 docker 运行时会出现 500 错误并超时。在上述烧瓶 API 应用程序中:

from flask import Flask, jsonify, request
from flask_restful import Api, Resource
... 
class AddCharacter(Resource):
    def post(self):
...
        p.add_person()
        # saves the character to a mongodb
        p.save_person() #<-- causes a 500 error in postman when run through docker build and docker up
        retJson = {
            "Message": "Character has been created",
            "Status Code": 200
        }
        return jsonify(retJson)

我如何连接到 mongo:

db = MongoEngine()

app = Flask(__name__)

app.config['MONGODB_SETTINGS'] = {
    'db': 'projectdb',
    'host': 'localhost',
    'port': 27017


}

with app.app_context():
    db.init_app(app)
    try:
        db_client = db.connection['projectdb']
    except ConnectionFailure as e:
        sys.stderr.write("Could not connect to MongoDB: %s" % e)
    sys.exit(1)

数据库管理员:

class DatabaseManager():

    def save_user(self, first_name, last_name, openness, conscientiousness, extraversion,
                  agreeableness, emotional_stability, organization, anxiety,
                  knowledgeableness, sympathy, talkativeness, accommodation,
                  expressiveness, carefulness, depressiveness, gregariousness,
                  altruism, inquisitiveness):
        new_user = User(first_name=first_name, last_name=last_name)
        new_user.save()
        new_personality = Personality(Openness=openness, Conscientiousness=conscientiousness, Extraversion=extraversion,
                                      Agreeableness=agreeableness, EmotionalStability=emotional_stability,
                                      Organization=organization, Anxiety=anxiety,
                                      Knowledgeableness=knowledgeableness, Sympathy=sympathy,
                                      Talkativeness=talkativeness, Accommodation=accommodation,
                                      Expressiveness=expressiveness, Carefulness=carefulness,
                                      Depressiveness=depressiveness, Gregariousness=gregariousness,
                                      Altruism=altruism, Inquisitiveness=inquisitiveness)
        new_profile = Profile(person=new_user, personality=new_personality)
        new_profile.save()

在 Person 类中:

def save_person(self):
    dm.save_user(first_name=self.first_name, last_name=self.last_name, openness=aff.Openness,
                 conscientiousness=aff.Conscientiousness, extraversion=aff.Extraversion,
                 agreeableness=aff.Agreeableness, emotional_stability=aff.EmotionalStability,
                 organization=aff.Organization, anxiety=aff.Anxiety,
                 knowledgeableness=aff.Knowledgeableness, sympathy=aff.Sympathy, talkativeness=aff.Talkativeness,
                 accommodation=aff.Accommodation,
                 expressiveness=aff.Expressiveness, carefulness=aff.Carefulness, depressiveness=aff.Depressiveness,
                 gregariousness=aff.Gregariousness,
                 altruism=aff.Altruism, inquisitiveness=aff.Inquisitiveness)

文件结构, Dockerfile, 要求.txt, .yml 文件图像。 我用sudo docker-compose build 运行docker,然后sudo docker-compose up

【问题讨论】:

  • 如果您的代码在本地而不是在 docker 上运行良好,则可能是您如何运行 docker 容器的问题。请添加您构建映像的方式以及运行方式。
  • 添加了额外的图像构建文件。我想添加说明,即 AddCharacter 在不尝试保存到 mongo 时在 docker 上运行良好。通过 docker 写入 mongo db 时,邮递员会超时。
  • 如何将烧瓶应用程序连接到 mongo?你用什么主机名?
  • 添加了我如何将烧瓶 app.py 连接到 mongo。我使用'localhost'和端口:27017。

标签: python-3.x mongodb docker flask postman


【解决方案1】:

从您的设置看来,主机正在运行数据库服务器,而您无法从容器的虚拟网络访问,您需要在这里做的是将主机网络和端口与容器的虚拟网络连接起来,以便您的根据您的应用程序配置,应用程序能够访问数据库,就像在同一主机上运行时一样。

默认情况下,docker 容器以桥接模式启动,在启动容器时没有明确指定网络模式,因此您可以将数据库服务器与桥接 IP 绑定,或者您可以指定网络模式来托管您的容器。

【讨论】:

  • 谢谢!如何以及在何处将主机网络和端口与容器的虚拟网络连接起来?
  • 要获取网桥 IP,您可以从容器内部运行 route 命令以查看路由表并将 db 服务器与该 IP 绑定,或者如果您只是想测试只有使用这台机器,您才能在启动 docker 容器时指定 --network="host" 标志。来源:for more info
【解决方案2】:

问题在于您从后端连接到 MongoDB 的方式。

请记住,docker 容器的localhost 与正在运行的主机不同,它指向容器本身(除非您在主机网络中运行容器)。因此,几乎 99% 的时间您都不想在 dockerized 环境中连接到 localhost

默认情况下,docker-compose 在运行的容器之间创建一个内部网络,这样你就可以通过它的服务名称来解析容器的 ip。也就是说,如果您将localhost 替换为db(您的数据库服务名称),您就可以连接到您的数据库。

【讨论】:

    【解决方案3】:

    我发现向 docker-compose.yml 添加网络解决了这个问题:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-16
      • 1970-01-01
      • 2020-11-16
      • 2016-07-09
      • 2021-11-07
      • 2020-12-11
      相关资源
      最近更新 更多