예제 #1
0
    def action_generate(self, data):
        """
        Метод обработчик действия generate.
        Данное действие отвечает за сохранение всех корректных данных,
        полученных и проверенных на этапе валидации.
        Для получения объектов моделей используется встроенный десериализатор,
        используемый в команде loaddata (так как он умеет только создавать
        объекты, а не обновлять их, используется несколько более сложный
        механизм вызова метода save у модели, нежели в десериализаторе).

        После добавления объектов в базу данных, pk новых объектов сохранаются
        в массиве и используются в дальнейшем при обработке нижестоящих
        в иерархии коллекций.
        """
        serialized = self.get_serialized_data(data)
        prepared = self.prepare_serialized_data(serialized)  # lazy
        deserialized = Deserializer(prepared)  # lazy

        self.log("\ngenerate                 %s " %
                 str(len(serialized)).ljust(5))
        for dobj, sobj in zip(deserialized, serialized):  # lazy
            if not self.require_to_save_object(dobj, sobj):
                sobj['source']['pk'] = dobj.object.pk
                char = '-'
            else:
                obj = self.get_deserialized_object(dobj, sobj)
                obj = self.save_deserialized_object(obj, dobj, sobj)
                sobj['source']['pk'] = obj.pk
                char = '+' if getattr(obj, '__is_new__', False) else '.'
            self.log(char)

        # clear query log
        db.reset_queries()
예제 #2
0
 def save_record(self, data, pk=None):
     if pk:  # If we are updating an existing record
         existing_record = self.get_record(pk)
         existing_record['fields'].update(data)
         save_data = [existing_record]
     else:  # If we are creating a new record
         data['uuid'] = str(uuid4())
         save_data = [{
             'fields':
             data,
             'model':
             '{}.{}'.format(self.model._meta.app_label,
                            self.model._meta.model_name),
         }]
     for obj in Deserializer(save_data):
         obj.save()
예제 #3
0
 def _test_json_field_after_serialization(serialized):
     for obj in Deserializer([serialized]):
         self.assertIsInstance(obj.object.auth_context, dict)
예제 #4
0
    def create(self, request):
        objects_in_fixture = 0
        loaded_objects_count = 0
        models = set()

        fixture = request.data.get('fixture')

        if fixture:
            with transaction.atomic():
                connection = connections[DEFAULT_DB_ALIAS]

                with connection.constraint_checks_disabled():
                    objects = Deserializer(fixture,
                                           ignorenonexistent=True,
                                           handle_forward_references=True)
                    objs_with_deferred_fields = []

                    for obj in objects:
                        objects_in_fixture += 1
                        if router.allow_migrate_model(DEFAULT_DB_ALIAS,
                                                      obj.object.__class__):
                            loaded_objects_count += 1
                            models.add(obj.object.__class__)
                            try:
                                obj.save()
                            # psycopg2 raises ValueError if data contains NUL chars.
                            except (DatabaseError, IntegrityError,
                                    ValueError) as e:
                                e.args = (
                                    "Could not load %(app_label)s.%(object_name)s(pk=%(pk)s): %(error_msg)s"
                                    % {
                                        'app_label':
                                        obj.object._meta.app_label,
                                        'object_name':
                                        obj.object._meta.object_name,
                                        'pk': obj.object.pk,
                                        'error_msg': e,
                                    }, )
                                raise
                        if obj.deferred_fields:
                            objs_with_deferred_fields.append(obj)

                    for obj in objs_with_deferred_fields:
                        obj.save_deferred_fields()

                if loaded_objects_count > 0:
                    sequence_sql = connection.ops.sequence_reset_sql(
                        no_style(), models)
                    if sequence_sql:
                        with connection.cursor() as cursor:
                            for line in sequence_sql:
                                cursor.execute(line)
                # Close the DB connection -- unless we're still in a transaction. This
                # is required as a workaround for an edge case in MySQL: if the same
                # connection is used to create tables, load data, and query, the query
                # can return incorrect results. See Django #7572, MySQL #37735.
            if transaction.get_autocommit():
                connections[DEFAULT_DB_ALIAS].close()

        return Response({"objects_loaded": loaded_objects_count},
                        status=status.HTTP_200_OK)