После вставки преобразуйте и вставьте в другую таблицу - PullRequest
0 голосов
/ 10 июля 2019

У меня есть две таблицы 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)

1 Ответ

0 голосов
/ 10 июля 2019

Как 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 подход.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...