我有一个Pyramid Web应用程序,我需要使用SQLAlchemy将上传的文件存储到Postgresql DB。我已经可以通过带有FormData
对象的AJAX调用来访问文件,并将其保存在变量中,但无法将其存储到SQLAlchemy模型中。
我曾尝试使用ControlFile.content = file_object.file
之类的东西,但收到以下错误:无法将_io.BytesIO转换为二进制文件
这是我的代码段
CREATE TABLE "control_file"(
-- ...
"content" bytea NOT NULL
-- ...
);
class ControlFile(BaseStatusAll):
__tablename__ = 'control_file'
content = Column(LargeBinary)
#...
@view_config(route_name='add_file_to_control', renderer='json', request_method='POST')
def add_file(request):
file_object = request.params.get('file')
cf = ControlFile()
cf.content = file_object.file
# SQLAlchemy session
request.dbsession.add(cf)
#...
return {'status': 1}
这是我用来上传文件的脚本。请注意,file
是File
对象(https://developer.mozilla.org/en-US/docs/Web/API/File)
var fd = new FormData();
fd.append("file", file);
$.ajax({
'url': '...',
'method':'POST',
'async': false,
cache: false,
contentType: false,
processData: false,
data: fd
});
这是一种解决方法,但我确定必须有更好的方法来做到这一点。
所以,总的来说,我要做的是
shutil
和字节字符串创建临时文件import shutil
# 1
cf = ControlFile()
request_file = file_object.file
# 2
with open('temp/' + file_object.filename, 'wb') as output_file:
shutil.copyfileobj(request_file, output_file)
# 3
with open('temp/' + file_object.filename, 'rb') as file:
cf.content = file.read()
# 4
# SQLAlchemy session
request.dbsession.add(cf)
# 5
os.remove('temp/' + file_object.filename)