Как правильно загрузить модуль mongodb? (Неперехваченная ошибка: имя модуля «mongodb» еще не загружено для контекста: _. Используйте require([]))

#javascript #python #node.js #mongodb #flask

#javascript #python #node.js #mongodb #flask

Вопрос:

Я пытаюсь создать веб-страницу на Flask, которая использует базу данных mongodb, но я не могу подключиться. Если я просто запускаю свои скрипты на python, все в порядке, я могу подключиться к базе данных, создавать документы и читать их, но на стороне Flask это, похоже, не работает. Все остальное на стороне Javascript работает просто отлично, кроме подключения к базе данных. Я использовал: https://www.w3schools.com/nodejs/nodejs_mongodb.asp для подключения. Я установил node.js это включает в себя npm: https://nodejs.org/en/download / отсюда.

Вот мои источники:

    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Publisher</title>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.js"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <script type="text/javascript" src="https://requirejs.org/docs/release/2.3.6/r.js"></script>
    </head>
 

Вот скрипт для подключения к базе данных:

 var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://127.0.0.1:56215/9414efbc-92ee-41a4-8666-3f98c5b6ec99?" //Temporary change it each time
var DB_Data = []

MongoClient.connect(url, function(err, db) {
  if (err) throw err;
  var dbo = db.db("IOT_Modbus_DB");
  dbo.collection("IOT_Modbus_Coll").find({}).toArray(function(err, result) {
    DB_Data = resu<
    if (err) throw err;
    db.close();
  });
});
 

Приведет к этой ошибке:

 r.js:417 Uncaught Error: Module name "mongodb" has not been loaded yet for context: _. Use require([])
https://requirejs.org/docs/errors.html#notloaded
    at makeError (r.js:417)
    at Object.localRequire [as require] (r.js:1685)
    at requirejs (r.js:2046)
    at update:50
 

Если я делаю то, что он рекомендует, это означает:

 var MongoClient = require(['mongodb']).MongoClient;
 

Я получаю это:

 Uncaught TypeError: Cannot read property 'connect' of undefined
    at update:54
r.js:2420 GET http://127.0.0.1:5000/mongodb.js 404 (NOT FOUND)
require.load @ r.js:2420
load @ r.js:1934
load @ r.js:1083
fetch @ r.js:1073
check @ r.js:1105
enable @ r.js:1425
enable @ r.js:1806
(anonymous) @ r.js:1410
(anonymous) @ r.js:383
each @ r.js:308
enable @ r.js:1362
init @ r.js:1037
(anonymous) @ r.js:1709
setTimeout (async)
req.nextTick @ r.js:2064
localRequire @ r.js:1698
requirejs @ r.js:2046
(anonymous) @ update:50
VM639:1 Uncaught SyntaxError: Unexpected token '<'
    at exec (r.js:2413)
    at XMLHttpRequest.xhr.onreadystatechange (r.js:2424)
Uncaught Error: Load timeout for modules: mongodb
https://requirejs.org/docs/errors.html#timeout
    at makeError (r.js:417)
    at checkLoaded (r.js:947)
    at r.js:968
 

Из того, что я прочитал, правильный способ сделать это — без «[]», но я попробовал на всякий случай. Я должен упомянуть, что у меня нет mongodb.js файл, так как я работал в одном HTML-файле. Я также попробовал другие ответы, предложенные людьми, у которых были похожие ошибки, но это не сработало.
Я также попробовал то, что сказал здесь: https://requirejs.org/docs/errors.html#notloaded кроме того, чтобы поместить его в функцию, но я не уверен, как это сделать.
Чего мне не хватает? Как я должен загрузить его для контекста?

Ниже я на всякий случай помещу файл Flask python. Также полный HTML-файл.

 from flask import Flask, render_template, jsonify
import json
import Modbus_Gw_Parsed
import Monitor_Host_Parsed
import pyModbus_Client
import DB_Modbus

app = Flask(__name__)

#TODO: calling

@app.route('/')
def Publisher_Display():
        return render_template('Publisher_Display.html')

@app.route('/update')
def update():
    Modbus_Gw_Parsed.runGw()
    Monitor_Host_Parsed.runHost()
    pyModbus_Client.runMod()
    DB_Modbus.Create_Db()
    return render_template('Publisher_Display.html')
    
if __name__ == '__main__':
  app.config['TEMPLATES_AUTO_RELOAD'] = True
  app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0
  app.run()
 

Publisher_Display.html:

 <!DOCTYPE html>
<html lang="en">

<style>
    canvas {
    -moz-user-select: none;
    -webkit-user-select: none;
    -ms-user-select: none;
}
</style>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Publisher</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script type="text/javascript" src="https://requirejs.org/docs/release/2.3.6/r.js"></script>
</head>

<body>
<!-- This will update the output files -->
<form action = "/update">
    <input type="submit" value="Fetch New Data">
</form>
<!--backend.py -->

    <div id="myData"></div>
    <div style="width:75%;">
        <canvas id="canvas"></canvas>
    </div>
<script>
    Promise.all([
    //Configuration Data: Represent the meaning of the important data
    fetch('/static/Monitor_Host_Publishers_Parsed.json').then(resp => resp.json()),
    fetch('/static/Modbus_Gw_File_Parsed.json').then(resp => resp.json()),
    //Publish Data: Display graphically
    fetch('/static/pyModbus.json').then(resp => resp.json())
          ]).then(function (data) {
                appendData(data);
                console.log(data);
                chart(data);
            })
            .catch(function (err) {
                console.log('error: '   err);
            });

//MongoDB
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://127.0.0.1:56215/9414efbc-92ee-41a4-8666-3f98c5b6ec99?" //Temporary change it each time
var DB_Data = []

MongoClient.connect(url, function(err, db) {
  if (err) throw err;
  var dbo = db.db("IOT_Modbus_DB");
  dbo.collection("IOT_Modbus_Coll").find({}).toArray(function(err, result) {
    DB_Data = resu<
    if (err) throw err;
    db.close();
  });
});

function appendData(data){
//Representing configuration data
  var mainContainer = document.getElementById("myData");
      var ip;
      for(var i=0; i<data[1].length; i  ){
          ip = data[1][i].Eui64;
          console.log(ip ': ' i)
          var div = document.createElement("div");
          div.innerHTML = '<br/>Address: ' data[1][i].start_addr 
                          '<br/>Number of Registers: ' data[1][i].word_cnt 
                          '<br/>Device: ' ip 
                          '<br/>Unit of measurement: ' data[0][ip].channel[0].unit_of_measurement 
                          '<br/>Status: ' data[0][ip].channel[0].withStatus '<br/>_';   
          mainContainer.appendChild(div);
      }  
}

function state_bulb(data){
//Temporary(?) State Checker    
//TODO: Show status
reg1 = data[1][0].status; // if is 2 the last register will represent the status
reg2 = data[1][1].status; // and not sensor value
/*
128 - Data is Fresh (green)
20 - Data is stale (yellow)
0 - Missing data or connection (red)
*/
}

function chart(data){
//Publish Data Chart
window.chartColors = {  red: 'rgb(255, 0, 0)',  green: 'rgb(0, 128, 0)', yellow: 'rgb(200, 200, 0)' }; 

var randomScalingFactor = function() {
            return Math.round(Math.random() * 100);
        };

var today = new Date();
var labelnames = [today.getHours()   ":"   today.getMinutes()   ":"   today.getSeconds()];
    
var count = data[2][0].response.length; //TODO: Make a max function to compare all data[2] lengths

var config = {
        type: 'line',
        data: { //TODO: Make number of datasets scale-able
            labels: labelnames,
            datasets: [{
                label: 'Register '  data[2][0].register,
                data: DB_Data[0].Value,
                borderColor: window.chartColors.green,
                backgroundColor: 'rgba(0, 0, 0, 0)',
                fill: false,
                cubicInterpolationMode: 'monotone'
            }, {
                label: 'Register '  data[2][1].register,
                data: DB_Data[1].Value,
                borderColor: window.chartColors.red,
                backgroundColor: 'rgba(0, 0, 0, 0)',
                fill: false,
                cubicInterpolationMode: 'monotone'
            }]
        },
        options: {
            responsive: true,
            title: {
                display: true,
                text: 'Configuration Chart'
            },
            tooltips: {
                mode: 'index'
            },
            scales: {
                xAxes: [{
                    display: true,
                    scaleLabel: {
                        display: true
                    }
                }],
                yAxes: [{
                    display: true,
                    scaleLabel: {
                        display: true,
                        labelString: 'Value'
                    },
                    ticks: {
                        suggestedMin: 0,
                        suggestedMax: 100,
                    }
                }]
            }
        },      
    };

var ctx = document.getElementById('canvas').getContext('2d');
window.myLine = new Chart(ctx, config);
}
</script>
</body>
</html>
 

Ответ №1:

Я понял это, но только частично. Поскольку я использую flask, я не могу использовать mongodb напрямую в js.

Я должен передать коллекцию или любую другую переменную, когда я отображаю html следующим образом:

 app = Flask(__name__)

    title = "IOT Project"
    
    client = MongoClient("mongodb://127.0.0.1:5000") #placeholder
    db = client["IOT_Modbus_DB"]
    col = client["IOT_Modbus_Coll"]
    
    @app.route('/')
    def Publisher_Display():
            return render_template('Publisher_Display.html', Data = col, t = title)
 

После этого их довольно легко вызвать в HTML

 <title>{{t}}</title>
 

При рендеринге заголовок будет отправлен как «t».
Я обновлю этот ответ, если выясню, как отправлять определенные данные из базы данных.

РЕДАКТИРОВАТЬ: на самом деле довольно просто:

 for x in col.find({ "Register": "1020000000000061" },{"_id": 0}):
  Reg1.append(x)
 

Вот как mongodb обрабатывает поиск. «_id»: 0 просто означает, что он не будет показывать идентификатор. После отправки этой переменной при рендеринге просто не забудьте сделать это следующим образом:

 {{ var | safe }}
 

если у вас есть строки, потому что, если вы делаете это так:

 {{ var }}
 

Вы получите кодировку amp; #39 вместо » или ‘