python - 插入后,转换并插入到另一个表中
问题描述
我有两张桌子Document
和Picture
. 关系是一个文档可以有几张图片。应该发生的情况是,一旦将文档上传到 . PostgreSQL
,该文档应该被下载并转换为 jpeg,然后上传到Picture
table。
我在我的应用程序中使用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)
解决方案
正如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#im-inserting-400-000-rows-with-the-orm-and-it -s-真的很慢
因此,当前的方法不是最快的方法,因此我会选择其中一个sqlalchemy_orm_bulk_insert
或sqlalchemy_core
方法。
推荐阅读
- c++ - 如何制作不同常量的元组?
- c++ - 这里的 RF() 是什么?这里绝对有必要吗?
- c++ - 通过 C++ 中的 Pthread_Create 打印通过结构传递的数组值
- c++ - 使用 BOOST 库求解微分方程
- c++ - OCX AfxOleRegisterTypeLib 失败并出现错误 0x80040200
- python - how define condition that ends while loop iteration of python list?
- hcatalog - 如何独立使用 Hive Metastore?
- ruby-on-rails - 翻译模型属性不起作用
- bash - 内联 ps aux while 循环
- proxy - TestCafe 获取正在使用的代理的当前 IP