通过表单创建员工和照片模型时,我遇到上述错误的问题。
我的方案是我使用Flask-Admin
创建一个Employee
模型,其中包含我创建的嵌套表单的关联Photo
(个人资料图片)。当我通过表单创建一个Employee及其关联的Photo时,我没有收到任何错误。但是,当我尝试通过表单创建另一个Employee和Photo时,我收到此错误:
DetachedInstanceError: Instance <Photo at 0x106eca0d0> is not bound to a Session; attribute refresh operation cannot proceed
我已经阅读了关于SQLAlchemy的关于Session
expunge
expunge_all()
flush
和级联的文档,但我仍然无法使其正常工作。我仍然收到同样的错误,我不确定还有什么可以尝试。
-----------编辑(代码和完整跟踪错误)----------------
这是表单代码
forms.py
class PhotoForm(Form):
-------conditional logic that determines s3 config or not -------
image = S3ImageUploadField(base_path=app.config['UPLOAD_FOLDER'],
namegen = photo_name_generator,
storage_type = '',
storage_type_field = '',
bucket_name = '',
bucket_name_field = '',
access_key_id = '',
access_key_secret = '',
static_root_parent = app.config['UPLOAD_FOLDER'])
DEPARTMENTS = ['place a series of tuples indicating department choices']
class EmployeeForm(Form):
name = StringField('Full Name', validators=[DataRequired()])
title = StringField('Job Title', validators=[DataRequired()])
email = StringField('Company Email', validators=[DataRequired()])
department = SelectField('Department', choices=DEPARTMENTS)
photo = FormField(PhotoForm)
这是型号代码
models.py
#-----photo_name_generator grabs the filename and changes it to the employees name------
def photo_name_generator(obj,file_data):
parts = path.splitext(file_data.filename)
return secure_filename(str(obj.employee[0].name) + str(parts[1]))
class Photo(db.Model):
__tablename__ = 'photos'
id = db.Column(db.Integer, primary_key=True)
image = db.Column(db.String(200))
storage_type_field = db.Column(db.String(255), default='')
bucket_name_field = db.Column(db.String(255), default='')
def __init__(self, image='', storage_type_field='', bucket_name_field=''):
self.image = image
self.storage_type_field = storage_type_field
self.bucket_name_field = bucket_name_field
def __repr__(self):
return '<Photo %r>' % self.image
class Employee(db.Model):
__tablename__ = 'employees'
id = db.Column(db.Integer, primary_key=True)
photo_id = db.Column(db.Integer, db.ForeignKey(Photo.id))
photo = db.relationship("Photo", backref='employee', cascade='all, delete-orphan', single_parent=True, uselist=False)
name = db.Column(db.String(200))
title = db.Column(db.String(200))
email = db.Column(db.String(200))
department = db.Column(db.String(200))
def __init__(self, name='', title='', email='', department='', photo=Photo()):
self.name = name
self.title = title
self.email = email
self.department = department
self.photo = photo
def __repr__(self):
return '<User %r>' % self.name
这是管理员代码
admin.py
class EmployeeView(ModelView):
form = EmployeeForm
def _list_thumbnail(view, context, model, name):
return Markup('<img height="100" width="100" src="%s">' % url_for('static',
filename= 'images/' + model.photo.image))
column_formatters = {
'photo': _list_thumbnail
}
form_extra_fields = {
'photo': ImageUploadField('Image', base_path=app.config['UPLOAD_FOLDER'])
}
def on_model_delete(self,model):
os.remove(app.config['UPLOAD_FOLDER'] + model.photo.image)
def is_accessible(self):
return flask_login.current_user.is_authenticated
admin.add_view(EmployeeView(Employee, db.session))
跟踪错误:
sqlalchemy.orm.exc.DetachedInstanceError
DetachedInstanceError: Instance <Photo at 0x1060d50d0> is not bound to a Session; attribute refresh operation cannot proceed
Traceback (most recent call last)
File "/Users/drubio/Desktop/blackduckflock/venv/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/Users/drubio/Desktop/blackduckflock/venv/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/Users/drubio/Desktop/blackduckflock/venv/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/Users/drubio/Desktop/blackduckflock/venv/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/Users/drubio/Desktop/blackduckflock/venv/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/drubio/Desktop/blackduckflock/venv/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/drubio/Desktop/blackduckflock/venv/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/drubio/Desktop/blackduckflock/venv/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/drubio/Desktop/blackduckflock/venv/lib/python2.7/site-packages/flask_admin/base.py", line 68, in inner
return self._run_view(f, *args, **kwargs)
File "/Users/drubio/Desktop/blackduckflock/venv/lib/python2.7/site-packages/flask_admin/base.py", line 359, in _run_view
return fn(self, *args, **kwargs)
File "/Users/drubio/Desktop/blackduckflock/venv/lib/python2.7/site-packages/flask_admin/model/base.py", line 1674, in create_view
model = self.create_model(form)
File "/Users/drubio/Desktop/blackduckflock/venv/lib/python2.7/site-packages/flask_admin/contrib/sqla/view.py", line 1004, in create_model
if not self.handle_view_exception(ex):
File "/Users/drubio/Desktop/blackduckflock/venv/lib/python2.7/site-packages/flask_admin/contrib/sqla/view.py", line 987, in handle_view_exception
return super(ModelView, self).handle_view_exception(exc)
File "/Users/drubio/Desktop/blackduckflock/venv/lib/python2.7/site-packages/flask_admin/contrib/sqla/view.py", line 999, in create_model
form.populate_obj(model)
File "/Users/drubio/Desktop/blackduckflock/venv/lib/python2.7/site-packages/wtforms/form.py", line 96, in populate_obj
field.populate_obj(obj, name)
File "/Users/drubio/Desktop/blackduckflock/venv/lib/python2.7/site-packages/wtforms/fields/core.py", line 807, in populate_obj
self.form.populate_obj(candidate)
File "/Users/drubio/Desktop/blackduckflock/venv/lib/python2.7/site-packages/wtforms/form.py", line 96, in populate_obj
field.populate_obj(obj, name)
File "/Users/drubio/Desktop/blackduckflock/venv/lib/python2.7/site-packages/flask_admin_s3_upload.py", line 58, in populate_obj
field = getattr(obj, name, None)
File "/Users/drubio/Desktop/blackduckflock/venv/lib/python2.7/site-packages/sqlalchemy/orm/attributes.py", line 237, in __get__
return self.impl.get(instance_state(instance), dict_)
File "/Users/drubio/Desktop/blackduckflock/venv/lib/python2.7/site-packages/sqlalchemy/orm/attributes.py", line 573, in get
value = state._load_expired(state, passive)
File "/Users/drubio/Desktop/blackduckflock/venv/lib/python2.7/site-packages/sqlalchemy/orm/state.py", line 480, in _load_expired
self.manager.deferred_scalar_loader(self, toload)
File "/Users/drubio/Desktop/blackduckflock/venv/lib/python2.7/site-packages/sqlalchemy/orm/loading.py", line 610, in load_scalar_attributes
(state_str(state)))
DetachedInstanceError: Instance <Photo at 0x1060d50d0> is not bound to a Session; attribute refresh operation cannot proceed
答案 0 :(得分:-1)
我能够通过在__init__.py
中指定以下代码来解决此问题。
db = SQLAlchemy(app,session_options={
'expire_on_commit': False
})