我有两个表Document
和Picture
。关系是一个文件可以有多张图片。应该发生的事情是,一旦将文档上传到PostgreSQL
,就应该下载该文档并将其转换为jpeg,然后再上传到Picture
表中。
我在应用程序中使用sqlalchemy
和flask
。
到目前为止,我尝试使用events
在插入后触发方法。不幸的是,我在提交时收到错误sqlalchemy.exc.ResourceClosedError: This transaction is closed
。
代码:
from app.models.ex_model import Document, Picture
from pdf2image import convert_from_bytes
from sqlalchemy import event
import io
import ipdb
from app.core.app_setup import db
@event.listens_for(Document, 'after_insert')
def receive_after_insert(mapper, connection, target):
document = target.document
images = convert_from_bytes(document, fmt='jpeg')
images_bytes = map(lambda img: convert_to_byte(img), images)
map(lambda img_byte: upload_picture(img_byte, target.id, ), images_bytes)
db.session.commit()
def convert_img_to_byte(img):
img_byte = io.BytesIO()
img.save(img_byte, format='jpeg')
img_byte = img_byte.getvalue()
return img_byte
def upload_picture(img_byte, document_id):
picture = Picture(picture=img_byte, document_id=document_id)
db.session.add(picture)
答案 0 :(得分:0)
Session.add
方法指出:
其状态将在下一个
flush
上保存到数据库中 操作。
对add()
的重复调用将被忽略。
因此,在您的add
呼叫之后应进行session.flush()
呼叫。
...
def upload_picture(img_byte, document_id):
picture = Picture(picture=img_byte, document_id=document_id)
db.session.add(picture)
db.session.flush()
此外,我将注意插入记录的性能。关于这一点,官方文档中有一篇不错的文章:https://docs.sqlalchemy.org/en/13/faq/performance.html#i-m-inserting-400-000-rows-with-the-orm-and-it-s-really-slow
因此,当前的方法不是最快的方法,因此我会选择sqlalchemy_orm_bulk_insert
或sqlalchemy_core
方法。