Flask Restless AttributeError:“NoneType”对象没有属性“_sa_instance_state”
Posted
技术标签:
【中文标题】Flask Restless AttributeError:“NoneType”对象没有属性“_sa_instance_state”【英文标题】:Flask Restless AttributeError: 'NoneType' object has no attribute '_sa_instance_state' 【发布时间】:2014-12-29 00:14:55 【问题描述】:我目前正在使用Flask
、Flask-SQLAlchemy
和Flask-Restless
为小型私有AngularJS 应用程序提供REST 路由。到目前为止,我已经能够有效地制作/使用不包含任何关系的路线。
但是,我有一些表必须与其他表有关系,这就是我的问题所在。向 Flask-Restless Route 发送 POST 时出现以下 Flask 错误:
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/usr/local/lib/python2.7/dist-packages/flask_restless/views.py", line 145, in decorator
return func(*args, **kw)
File "/usr/local/lib/python2.7/dist-packages/mimerender.py", line 227, in wrapper
result = target(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/flask/views.py", line 84, in view
return self.dispatch_request(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/flask/views.py", line 149, in dispatch_request
return meth(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/flask_restless/views.py", line 1263, in post
self.session.add(instance)
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/scoping.py", line 150, in do
return getattr(self.registry(), name)(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/session.py", line 1492, in add
self._save_or_update_state(state)
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/session.py", line 1510, in _save_or_update_state
halt_on=self._contains_state):
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/mapper.py", line 2457, in cascade_iterator
visited_states, halt_on))
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/relationships.py", line 1449, in cascade_iterator
get_all_pending(state, dict_)
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/dynamic.py", line 185, in get_all_pending
c.all_items
AttributeError: 'NoneType' object has no attribute '_sa_instance_state'
我认为这个错误与我的模型有关。以下是我当前的模型定义:
surveyOptions = db.Table('survey_options',
db.Column('survey_id', db.Integer, db.ForeignKey('survey.id')),
db.Column('option_id', db.Integer, db.ForeignKey('option.id')),
db.Column('count', db.Integer)
)
class Survey(db.Model):
id = db.Column(db.Integer, primary_key=True)
category = db.Column(db.String(50))
question = db.Column(db.Text)
startDate = db.Column(db.DateTime)
endDate = db.Column(db.DateTime)
options = db.relationship('Option', secondary=surveyOptions,
backref=db.backref('surveys', lazy='dynamic'), lazy='dynamic')
def __init__(self, category, question, startDate=None, endDate=None, options=None):
self.category = category
self.question = question
if startDate == None:
self.startDate = datetime.utcnow()
if endDate == None:
self.endDate = datetime.utcnow()
self.options.append(options)
class Option(db.Model):
id = db.Column(db.Integer, primary_key=True)
text = db.Column(db.Text)
def __init__(self, text):
self.text = text
...
manager = flask.ext.restless.APIManager(app, flask_sqlalchemy_db=db)
manager.create_api(Survey, methods=['GET','POST','PUT','DELETE'], include_columns=['id','category', 'question', 'startDate','endDate', '_options.id','options.text']);
非常感谢您在隔离此错误的来源方面提供的帮助。我不确定下一步该去哪里解决此错误。
如果需要,我可以根据要求为前端和后端提供更多代码示例。
【问题讨论】:
当你得到一个None
而不是一个对象时,通常会出现 NoneType 错误。但是我在您的代码中看不到哪个对象具有该属性。同样在您的错误日志中只有回溯中的库,因此它不应该在您的模型中
那么 Angular 向服务器发送的内容可能有问题?
可能是因为你在函数定义中有 options=None 然后 make self.options.append(options)?
【参考方案1】:
这是因为您似乎在此部分中附加了一个带有列表的列表:
def __init__(self, category, question, startDate=None, endDate=None, options=None):
self.category = category
self.question = question
if startDate == None:
self.startDate = datetime.utcnow()
if endDate == None:
self.endDate = datetime.utcnow()
self.options.append(options) # assuming options is a list, this will fail.
出现问题的原因很简单。如果我有我的选项列表:
foo = ['one', 'two']
我想再添加几个选项:
bar = ['three', 'four']
如果我foo.append(bar)
我得到:
foo = ['one', 'two', ['three', 'four']]
而您实际上是在寻找 foo + bar
这会给您:
foo = ['one', 'two', 'three', 'four']
当你解决了这个问题时,你仍然会遇到第二个奇怪的问题——如果你在创建 Survey
对象时没有指定 options
,那么,就目前而言,你的代码将尝试self.options.append(None)
给你的对象。您需要为此添加一个检查:
if choices: # None or [] will evaluate to False
self.choices += choices
我还注意到您使用 ==
运算符与 None
进行比较,您真的应该使用 is
进行这些比较,例如if startDate is None:
.
【讨论】:
以上是关于Flask Restless AttributeError:“NoneType”对象没有属性“_sa_instance_state”的主要内容,如果未能解决你的问题,请参考以下文章
Flask-Restless 的复杂路由(例如“忘记密码”)
使用 flask-restless 对 POST 的错误请求与关系