【问题标题】:getting invalid document error while querying mongodb database查询 mongodb 数据库时出现无效文档错误
【发布时间】:2020-04-21 23:29:50
【问题描述】:

我在查询我的 mongodb 数据库时遇到此错误:bson.errors.InvalidDocument: 文档必须只有字符串键,键是 函数位置在 0x7f50be59ac80,我的数据库集合看起来像这样(见下图

这是代码

@app.route('/request books', methods=['GET', 'POST'])
@app.route('/get books', methods=['GET', 'POST'])
def requesting_for_books():
    try:
        mydb = mongo.db.mylogin
        user_col = mydb.find_one({"email" : session['email']})
        final = dict(user_col)
        verify = final['isVerified']
        form = RequestBooks()
        if ('email' in session and verify == True) and ('password' in session and request.method == 'GET'):
            return render_template('get_books.html', title="Get Books", donated_by=session['username'], form=form)
        elif 'email' in session and request.method == 'POST':
            requesting = mongo.db.mylogin   
            request_books = requesting.find({ location: { "$nearSphere": { "$geometry" : {"type" : "Point",  "coordinates": [session['lat'], session['lang']]} } } })

            x = []
            for i in request_books:
            x.append(i)
            real_data = x
            if request_books == None:
                flash("Please enter a search query !")
                return render_template('get_books.html', title='Get Books', form=form)
            else:
                return render_template('get_books.html', title="Get Books", request_books=request_books[0], form=form)
        else:
            flash('Please Login/Sign Up first to Search for books !')
            return redirect(url_for('home'))
    except KeyError:
        flash("Please Sign in first !")
        return render_template('index.html', title="Home")

但是,如果我遍历 request_books 变量,我可以得到 我的文档的 pymongo 光标值

请帮忙!

【问题讨论】:

    标签: python-3.x mongodb variables flask pymongo


    【解决方案1】:

    查询中的location 应该是一个字符串,用单引号或双引号括起来。 可能你在模块的其他地方(或在其他用form module_name import * 调用的模块中)有一个名为location 的函数。

    您可以通过一些编辑使代码更简单/更具可读性:

    # since REST APIs have the get and set verb embedded into the HTTP method,
    # just use "books" (this is a personal preference, though)
    @app.route('/books', methods=['GET', 'POST'])
    def requesting_for_books():
        mydb = mongo.db.mylogin
        # it's better to handle exception as soon as they arise,
        # with the added bonus that you don't need to check 
        # if email is in session in the following statements
        try:
            user_col = mydb.find_one({"email" : session['email']})
        except KeyError:
            flash("Please Sign in first !")
            return render_template('index.html', title="Home")
        # user_col is already a dictionary, no need to transform it
        verify = user_col['isVerified']
        form = RequestBooks()
        # if the code runs until here, then email must be in session, no need to check
        # `== True` can be omitted
        if verify and 'password' in session and request.method == 'GET':
            return render_template(
               'get_books.html',
               title="Get Books",
               donated_by=session['username'],
               form=form
            )
        # since you returned in the previous if,
        # there's no need for an else/elif statement, just use if again
        if request.method == 'POST':
            # I suppose this is wrong,
            # it should be point to the books collection and not mylogin collection
            requesting = mongo.db.mylogin
            # if you need only the first element, just use find_one
            request_books = requesting.find_one({
                "location": {
                    "$nearSphere": {
                        "$geometry" : {
                            "type" : "Point",
                            "coordinates": [session['lat'], session['lang']]
                        }
                     }
                }
            })
            # you can pass request_books to render_template even if it is None
            # and handle the presence of data directly in the template
            return render_template(
                'get_books.html',
                title="Get Books",
                request_books=request_books,
                form=form
            )
        # no need to use "else", since you returned from the other branches
        flash('Please Login/Sign Up first to Search for books !')
        return redirect(url_for('home'))
    

    如果您想获取所请求书籍的列表,您可以简单地使用查找功能并将光标转换为列表,这样您将获得一个字典列表:

    request_books = list(requesting.find({
        "location": {
            "$nearSphere": {
                "$geometry" : {
                    "type" : "Point",
                    "coordinates": [session['lat'], session['lang']]
                }
            }
        }
    }))
    

    【讨论】:

    • 是的,我注意到早些时候顺便说一句感谢您的帮助!
    猜你喜欢
    • 2020-05-25
    • 1970-01-01
    • 2017-04-13
    • 2017-01-02
    • 2014-08-21
    • 1970-01-01
    • 2017-04-26
    • 1970-01-01
    • 2020-04-07
    相关资源
    最近更新 更多