无法在SQLAlchemy烧瓶中的结果对象上设置属性 [英] Can't set attribute on result objects in SQLAlchemy flask

查看:49
本文介绍了无法在SQLAlchemy烧瓶中的结果对象上设置属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了Flask-SQLAlchemy问题,可以在 place_collections 中设置对象的属性,但是当我想为 places 中的对象设置属性时,发生错误:

I encounter a problem with Flask-SQLAlchemy, I can set the attribute of the objects in place_collections, but when I want to set the attribute for objects in places, an error occurred:

Traceback (most recent call last):
  File "/Users/user/PycharmProjects/website/venv/lib/python3.6/site-packages/flask/app.py", line 2309, in __call__
    return self.wsgi_app(environ, start_response)
  File "/Users/user/PycharmProjects/website/venv/lib/python3.6/site-packages/werkzeug/contrib/fixers.py", line 152, in __call__
    return self.app(environ, start_response)
  File "/Users/user/PycharmProjects/website/venv/lib/python3.6/site-packages/flask/app.py", line 2295, in wsgi_app
    response = self.handle_exception(e)
  File "/Users/user/PycharmProjects/website/venv/lib/python3.6/site-packages/flask/app.py", line 1741, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/user/PycharmProjects/website/venv/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/Users/user/PycharmProjects/website/venv/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "/Users/user/PycharmProjects/website/venv/lib/python3.6/site-packages/flask/app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/Users/user/PycharmProjects/website/venv/lib/python3.6/site-packages/flask/app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/user/PycharmProjects/website/venv/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/Users/user/PycharmProjects/website/venv/lib/python3.6/site-packages/flask/app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Users/user/PycharmProjects/website/venv/lib/python3.6/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/user/Document/Python/Test/Code/app/main/views.py", line 108, in index
    place.distance = round(distance_computing, 1)
AttributeError: can't set attribute

如何设置联接搜索对象的属性,有人可以帮助我吗?

How can I set the attribute for join search object, could anyone help me?

place_collections = Place.query.filter_by(county='BKK')

places = db.session.query(Place.roll_number, Place.name, Place.website, Place.address, Place.distance)
            .outerjoin(Rank, Rank.place_id == Place.place_id)

它们都是 class'flask_sqlalchemy.BaseQuery'类型.

for place in place_collections:
       distance_computing = Place.distance_calculator(float(place.lat), float(place.lng),
                                                            data['lat'], data['lng'])

       place.distance = round(distance_computing, 1)


for place in places:
       distance_computing = Place.distance_calculator(float(school.lat), float(school.lng),
                                                            data['lat'], data['lng'])

       place.distance = round(distance_computing, 1)

模型

class Rank(db.Model):
    __tablename__ = 'rank'
    place_id = db.Column(db.String(50))
    name = db.Column(db.String(255), nullable=False, primary_key=True)
    rank = db.Column(db.Integer)

class Place(db.Model):
    _tablename_ = 'school'
    place_id = db.Column(db.String(50), primary_key=True)
    roll_number = db.Column(db.String(50))
    name = db.Column(db.String(255), nullable=False)
    address = db.Column(db.String(255))
    distance = db.Column(db.String(50))
    rank = db.relationship('Rank',backref=db.backref('roll_number1'), lazy=True, uselist=False)

推荐答案

place_collections = Place.query.filter_by(county='BKK')将为您返回Place对象的集合.这类似于普通香草SQLAlchemy中的session.query(Place).filter_by(county='BKK').

place_collections = Place.query.filter_by(county='BKK') will return you a collection of Place objects. This is analogous to session.query(Place).filter_by(county='BKK') in plain vanilla SQLAlchemy.

但是,从SQLAlchemy中文档:

However, from the SQLAlchemy docs:

查询还接受ORM插入的描述符作为参数.任何 时间多个类实体或基于列的实体表示为 query()函数的参数,返回结果表示为 元组

The Query also accepts ORM-instrumented descriptors as arguments. Any time multiple class entities or column-based entities are expressed as arguments to the query() function, the return result is expressed as tuples

关键点是,当您指定要查询的特定列时,就像在此处所做的那样:

The key point being that when you specify specific columns to query as you have done here:

places = db.session.query(Place.roll_number, Place.name,
    Place.website, Place.address, Place.distance).\
    outerjoin(Rank, Rank.place_id == Place.place_id)

结果表示为tuples的集合.

我的第一印象是can't set attribute是从尝试将属性值分配给tuple时收到的奇怪错误消息,所以我尝试了它:

My first impression was that can't set attribute was a strange error message to receive from trying to assign an attribute value to a tuple, so I tried it:

>>> t = tuple()
>>> t.attribute = 9
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'attribute'

那不是您收到的错误消息.

That's not the error message that you received.

因此,我执行了与您的第二次查询类似的查询(该模型只是我打开的项目中的内容):

So I performed a query similar to your second one (the model is just something from a project that I had open):

>>> q = session.query(Racecard.id, Racecard.meeting)
>>> a_result = q[0]
>>> type(a_result)
<class 'sqlalchemy.util._collections.result'>

对,所以我们没有得到一个元组,我们得到了一个sqlalchemy.util._collections.result对象.但是..

Right, so we aren't getting a tuple, we get a sqlalchemy.util._collections.result object. But..

>>> issubclass(type(a_result), tuple)
True

因此,sqlalchemy.util._collections.result tuple类型.

如果我们尝试为不是查询的列之一的属性分配值:

If we try to assign a value to an attribute that is not one of the columns that were queried:

>>> a_result.newattribute = 'something'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'result' object has no attribute 'newattribute'

该错误消息与将属性分配给普通tuple之前获得的错误消息非常相似.

That error message is very similar to the one that we got before when assigning an attribute to a plain tuple.

那您为什么会收到其他错误消息? result对象实际上更像是namedtuple:

So why did you get a different error message? The result object is actually more like a namedtuple:

>>> from collections import namedtuple
>>> Racecard = namedtuple('Racecard', 'id, meeting')
>>> rc = Racecard(1, 'Doomben')
>>> rc.meeting = 'Eagle Farm'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute

与您得到的错误消息相同.

Which is the same error message that you are getting.

因此,sqlalchemy.util._collections.result对象支持对列名称的属性访问,但是由于它是tuple,因此仍然是不可变的,因此您无法写入这些属性.

So, the sqlalchemy.util._collections.result object supports attribute access of the column names, but as it is a tuple it is still immutable, so you cannot write to those attributes.

要解决您的特定错误(除非出于某些原因,您仅专门查询那些列)将您的places查询更改为:

To fix your specific error (unless there was some reason that you were specifically querying only those columns) change your places query to:

places = db.session.query(Place).outerjoin(Rank, Rank.place_id == Place.place_id)

这篇关于无法在SQLAlchemy烧瓶中的结果对象上设置属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆