Flask Many to Many Column产生AttributeError:' NoneType'对象没有属性' _sa_instance_state'

时间:2016-07-13 15:06:33

标签: flask flask-sqlalchemy

当在view.py中创建组时,我想为group.users的许多用户创建[引用from_json(在model.py中)]

然而,一旦用户不重要,但很多用户就是那个问题

'AttributeError: 'NoneType' object has no attribute '_sa_instance_state''

model.py

user_group_relationship = db.Table('user_group_relationship',
                            db.Column('user_id', db.Integer,
                            db.ForeignKey('users.id'), nullable=False),
                            db.Column('group_id', db.Integer,
                            db.ForeignKey('groups.id'), nullable=False),
                            db.PrimaryKeyConstraint('user_id',`enter code here`'group_id'))

class User(db.Model):
     __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), unique=True, index=True)
    realname = db.Column(db.Text)
    password_hash = db.Column(db.String(128))
    confirmed = db.Column(db.Boolean)
    picture = db.Column(db.Text)
    groups = db.relationship('Group', 
            secondary=user_group_relationship, 
            backref=db.backref('user', lazy='dynamic'),
            lazy='dynamic')
    news = db.relationship('News', backref='author', lazy='dynamic')
    comments = db.relationship('Comment', backref='author', lazy='dynamic')


class Group(db.Model):
    __tablename__ = 'groups'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True, index=True)
    description = db.Column(db.Text)
    created_at = db.Column(db.DateTime, index=True, default=datetime.utcnow)

    users = db.relationship('User', 
            secondary=user_group_relationship, 
            passive_deletes=True,
            backref=db.backref('group', lazy='dynamic'),
                lazy='dynamic')
    news = db.relationship('News', backref='house', lazy='dynamic')

    def from_json(json_group)
        name = json_group.get('name')
        if name is None or name == '':
            raise ValidationError('group does not have a name')
        description = json_group.get('description')
        group = Group(name, description)
        users = json_group.get('users')

        if type(users) == list and users is not None and len(users) >= 1:  
        group.users = [ User.query.filter_by(id=user_id).first() for user_id in users]\
            if User.query.filter_by(id=user_id).count() != 0 ]
    return group

这是我的视图模型。创建组时,Group已从模型

引用from_json
@api.route('/groups', methods=['POST']) 
@auth.login_required
@cross_origin(expose_headers='Location')
def post_group():
    group = Group.from_json(request.json)
    if Group.query.filter_by(name=group.name).count() != 0:
        return forbidden('Already name is exist')
    db.session.add(group)
    db.session.commit()
    resp = make_response()
    resp.headers['Location'] = url_for('api.get_group', group_id=group.id)
    return resp

此处的调试日志

<!--

Traceback (most recent call last):
  File "/home/ju1115kr/venv/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/home/ju1115kr/venv/lib/python2.7/site-packages/flask_cors/extension.py", line 188, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "/home/ju1115kr/venv/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/ju1115kr/venv/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/ju1115kr/venv/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/ju1115kr/venv/lib/python2.7/site-packages/flask_cors/extension.py", line 188, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "/home/ju1115kr/venv/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/ju1115kr/venv/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/ju1115kr/venv/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/ju1115kr/venv/lib/python2.7/site-packages/flask_httpauth.py", line 62, in decorated
    return f(*args, **kwargs)
  File "/home/ju1115kr/venv/lib/python2.7/site-packages/flask_cors/decorator.py", line 127, in wrapped_function
    resp = make_response(f(*args, **kwargs))
  File "/home/ju1115kr/afoccert/app/api_1_0/groups.py", line 60, in post_group
    group = Group.from_json(request.json)
  File "/home/ju1115kr/afoccert/app/models.py", line 181, in from_json
    group.users = [ User.query.filter_by(id=user_id).first() for user_id in users]
  File "/home/ju1115kr/venv/lib/python2.7/site-packages/sqlalchemy/orm/attributes.py", line 224, in __set__
    instance_dict(instance), value, None)
  File "/home/ju1115kr/venv/lib/python2.7/site-packages/sqlalchemy/orm/dynamic.py", line 139, in set
    self._set_iterable(state, dict_, value)
  File "/home/ju1115kr/venv/lib/python2.7/site-packages/sqlalchemy/orm/dynamic.py", line 161, in _set_iterable
    collection_history=collection_history)
  File "/home/ju1115kr/venv/lib/python2.7/site-packages/sqlalchemy/orm/dynamic.py", line 99, in fire_append_event
    value = fn(state, value, initiator or self._append_token)
  File "/home/ju1115kr/venv/lib/python2.7/site-packages/sqlalchemy/orm/attributes.py", line 1190, in emit_backref_from_collection_append_event
    passive=PASSIVE_NO_FETCH)
  File "/home/ju1115kr/venv/lib/python2.7/site-packages/sqlalchemy/orm/dynamic.py", line 202, in append
    self.fire_append_event(state, dict_, value, initiator)
  File "/home/ju1115kr/venv/lib/python2.7/site-packages/sqlalchemy/orm/dynamic.py", line 99, in fire_append_event
    value = fn(state, value, initiator or self._append_token)
  File "/home/ju1115kr/venv/lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.py", line 46, in append
    sess._save_or_update_state(item_state)
  File "/home/ju1115kr/venv/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 1606, in _save_or_update_state
    halt_on=self._contains_state):
  File "/home/ju1115kr/venv/lib/python2.7/site-packages/sqlalchemy/orm/mapper.py", line 2610, in cascade_iterator
    visited_states, halt_on))
  File "/home/ju1115kr/venv/lib/python2.7/site-packages/sqlalchemy/orm/relationships.py", line 1528, in cascade_iterator
    get_all_pending(state, dict_)
  File "/home/ju1115kr/venv/lib/python2.7/site-packages/sqlalchemy/orm/dynamic.py", line 185, in get_all_pending
    c.all_items
AttributeError: 'NoneType' object has no attribute '_sa_instance_state'

1 个答案:

答案 0 :(得分:0)

由我自己解决。

何时

users = json_group.get('users')

    if type(users) == list and users is not None and len(users) >= 1:  
    group.users = [ User.query.filter_by(id=user_id).first() for user_id in users]\
        if User.query.filter_by(id=user_id).count() != 0 ]

users的类型是unicode。 所以,

>>> users=['ju1115kr']


>>> type(users)
>>> unicode
>>> for i in users:
>>>     print i
   [
   '
   j
   u
   1
   1
   1
   5
   k
   r
   '
   ]

所以我修好了

user_list = [ str(user) for user in users.strip('[]').split(',') ]
if type(user_list) == list and user_list is not None and len(user_list) >= 1:  
    group.users = [ User.query.filter_by(id=user_id).first() for user_id in user_list]\
        if User.query.filter_by(id=user_id).count() != 0 ]