사용자가 파일을 업로드 할 수있는 플라스크 기반 웹 앱이 있습니다. 파일은 mysql 데이터베이스에 저장된다.pymysql로 큰 blob을 삽입하려고 할 때 깨진 파이프
파일이 경우 16MB 이상 될 때까지 잘 작동이 삽입은 다음과 실패 다음 파일 크기가 max_allowed_packet
설정 MySQL의에 맞게 나타 났을 때 나는 흥분
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1518, in __call__
return self.wsgi_app(environ, start_response)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1506, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1504, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1264, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1262, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1248, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/<redacted>/access_control.py", line 15, in decorated_function
return f(*args, **kwargs)
File "/<redacted>/views/files.py", line 48, in upload
VALUES (%s, %s, %s, %s, %s)""", file_details)
File "/<redacted>/database.py", line 66, in query
cursor.execute(sql, values)
File "/usr/local/lib/python2.7/dist-packages/pymysql/cursors.py", line 262, in execute
result = super(DictCursor, self).execute(query, args)
File "/usr/local/lib/python2.7/dist-packages/pymysql/cursors.py", line 117, in execute
self.errorhandler(self, exc, value)
File "/usr/local/lib/python2.7/dist-packages/pymysql/connections.py", line 187, in defaulterrorhandler
raise Error(errorclass, errorvalue)
Error: (<class 'socket.error'>, error(32, 'Broken pipe'))
, 그래서 나는 my.cnf
에 변경 다시 시작했지만 도움이되지 않았습니다. (show variables like 'max_allowed_packet'
은 새로운 150M 값을 보여줍니다.)
파일이 서버에 확실히 업로드되고, 필자는 쿼리를 실행하기 전에 파일을 디스크에 쓰는 코드를 삽입 메소드에 넣었습니다.
블롭에 삽입되고있는 필드가 LONGBLOB 인, 삽입을 담당하는 코드는 다음과 같습니다
지금 손실의 비트에있어@mod.route('/file/upload', methods=['POST'])
@login_required
def upload():
filename = request.files['file'].filename
mime_type = request.files['file'].mimetype
#filesize = request.files['file'].content_length
file = request.files['file'].stream.read()
if mime_type[:5] == 'image':
file = resize_image_to_width(file, 1024)
filesize = len(file)
if filesize == 0:
return ""
if not request.form['file_id']:
file_details = (filename, file, mime_type, filesize, session['user']['user_id'])
file_id = database.query("""INSERT INTO files (filename, file, mime_type, filesize, owner)
VALUES (%s, %s, %s, %s, %s)""", file_details)
else:
file_details = (filename, file, mime_type, filesize, request.form['file_id'])
file_id = database.query("""UPDATE files
SET
filename=%s,
file=%s,
mime_type=%s,
filesize=%s
WHERE file_id=%s""", file_details)
return "upload complete"
, 나는 일주일에 몇 가지 물건을 찾을 않았거나 전에는 파일을 섹션에 삽입해야한다고 제안했지만 지금은 찾을 수 없습니다 (실제 작업에 정신이 없습니다!). 그리고 그것을 덩어리로 삽입하는 방법을 모르겠습니다.
정말 고맙겠습니다.
감사합니다. 이것은 한 걸음 더 나아갑니다. 파일을 청크로 나누고 각 청크를 추가하는 메소드를 프로토 타입했습니다. 파일을 다운로드 할 수 없으면'select' 쿼리는 파일이 ~ 16MB보다 큰 빈 결과를 반환합니다. 나는 역으로 같은 것을 할 필요가 있다고 생각하지만, 어떻게? 이상적으로 나는 오히려 1 거래에 더 큰 물건을 삽입 할 수있을 것입니다! – MalphasWats
선택에 문제가 없어야합니다. 대형 BLOB가 올바르게 작성되었는지 여부를 mysql 클라이언트에서 직접 확인하는 것이 좋습니다. –
큰 BLOB가 phpmyadmin을 사용하여 올바르게 작성되었으므로 BLOB 필드의 내용을 저장하고 적절한 확장자로 이름을 바꾸면 파일이 열립니다. pymysql을 통해 파일을 쿼리하려고하면 빈 결과가 나타납니다. 'select'는'insert'와 같은 제약을받습니다. – MalphasWats