импорт данных django-import-export не создает объекты в задаче сельдерея - PullRequest
0 голосов
/ 11 октября 2019

Я создал задачу celery в проекте для asinc создания объектов в моей модели, используя django-import-export. Задача запускается и все окей на локальной машине, но на объектах сервера не создается. Вот мой код: signal.py:

@receiver(post_save, sender=BuildingProductUploadFile)
def building_product_upload_file(instance, sender, **kwargs):
if kwargs.get('created'):
    if instance.status == BuildingProductUploadFile.NEED_PROCESSING:
        transaction.on_commit(import_building_product.s(instance.pk).delay)

tasks.py:

@celery.task(bind=True)
def import_data(self, dataset, building, resource):
    logger.info(f'start import')
    return resource.import_data(
        dataset,
        building=building,
        use_transactions=True,
    )

@celery.task(bind=True)
def import_building_product(self, upload_id):
    logger.info(f'start task: {self.name}')
    dataset = Dataset()
    product_resource = ImportProductBuildingResource()
    upload_file = BuildingProductUploadFile.objects.get(id=upload_id)
    logger.info(f'get file id: {upload_file.id}')
    try:
        with open(upload_file.file.path, 'rb') as file:
            dataset.xls = file.read()
        result = import_data(
            dataset,
            building=upload_file.building,
            resource=product_resource
        ).delay()
    logger.info(f'result: {result.rows}')
    upload_file.log_journal['info']['totally_rows'] = result.total_rows
    # upload_file.log_journal['total'] = result.total
    upload_file.status = BuildingProductUploadFile.COMPLETE
    error_list = []
    for num_row, row in enumerate(result.rows):
        if row.import_type == row.IMPORT_TYPE_ERROR:
            upload_file.status = BuildingProductUploadFile.COMPLETE_WITH_ERRORS
            logger.info(f'error in row task: {num_row}')
            # errors = [element.error for element in row.errors]
            # error_list.append(formatting(
            #     num=num_row,
            #     row=row.errors[0].row,
            #     errors=errors,
            #     debug_mode=settings.DEBUG_UPLOAD_GEAR
            # ))
    upload_file.log_journal['error_log'] = error_list
    logger.info(f'error list task: {error_list}')
except XLRDError:
    upload_file.log_journal['error_log'].append("Для загрузки требуется файл формата xlsx или xls.")
except Exception as err:
    upload_file.log_journal['error_log'].append(err.__repr__())
finally:
    self.update_state(
        state="COMPLETED"
    )
    logger.info(f'file status: {upload_file.status}')
    if upload_file.status == BuildingProductUploadFile.NEED_PROCESSING:
        upload_file.status = BuildingProductUploadFile.COMPLETE
    upload_file.save()
    logger.info(f'file status after save: {upload_file.status}')
    logger.info(f'end task: {self.name}')

import_utils.py:

from decimal import InvalidOperation

from import_export import resources
from import_export.fields import Field
from import_export.widgets import DecimalWidget, CharWidget

from apps.building.models import ProductBuilding


class ImportProductBuildingResource(resources.ModelResource):
number = Field(
    column_name='Обоснование',
    attribute='number',
    widget=NumberWidget()
)
name = Field(
    column_name=ProductBuilding._meta.get_field('name').verbose_name,
    attribute='name',
    widget=NameWidget()
)
count = Field(
    column_name='Количество',
    attribute='count',
)
price = Field(
    column_name='Цена',
    attribute='price',
    widget=PriceWidget()
)
building = Field(attribute='building')

class Meta:
    model = ProductBuilding
    fields = (
        'id',
        'number',
        'name',
        'count',
        'price',
        'building',
    )
    import_id_fields = ('building', 'number',)

def before_import_row(self, row, **kwargs):
    row['building'] = kwargs['building']
    return super(ImportProductBuildingResource, self).before_import_row(row, **kwargs)

Когда задача завершает объекты в моделиProductBuilding не создает. Что я должен пройти? Почему на локальной машине все работает нормально?

...