Рубрики
Без рубрики

Универсальная утилита клонирования

Универсальная утилита клонирования для объектов модели Django.

Автор оригинала: Apoorva Somani.

Обо мне

Я инженер полного стека, который работает с Django уже почти два года.

Проблема, которую я хотел решить

У нас было несколько действий, когда необходимо было скопировать данные из одной модели или создать клон записей в одной и той же модели. Во всех таких действиях у нас были условия, при которых иногда приходилось копировать только несколько полей, или некоторые поля приходилось игнорировать, или для некоторых полей требовалось предоставить какое-то другое значение. Это также означало, что нам нужно было написать один и тот же код для разных типов полей. Каждый раз, когда нам приходилось выполнять клонирование или копирование, мы заканчивали тем, что писали много кода, который был не только избыточным, но и сложным в обслуживании и масштабировании.

Что такое Универсальная утилита клонирования?

Я решил разработать универсальную утилиту клонирования, которая могла бы копировать данные из любого объекта модели в любой другой объект модели. Он может копировать все виды полей в Django — от простого CharField до сложного TreeForeignKey . Вы можете указать, какое поле необходимо скопировать или клонировать, любое значение, которое необходимо установить, или любые поля, которые необходимо игнорировать. Кроме того, вы можете выполнить массовое копирование и bulkclone, чтобы оптимизировать нагрузку на создание базы данных.

Технический стек

Я использовал Python и Django, так как мы использовали это в нашем проекте. Я говорю Python и Django, потому что эта утилита была исправлена на Django models class и использовала некоторые методы, определенные с помощью models и полей классов внутри.

Процесс создания утилиты генетического клонирования

Первым и главным шагом в написании утилиты клонирования было определение того, как различные типы полей, доступных в Django, могут быть скопированы из одного объекта модели в другой. Некоторые поля можно просто скопировать с помощью метода setattr , но некоторые поля, такие как ManyToMany field и TreeForeignKey , требуют некоторой обработки, прежде чем их можно будет скопировать.

Затем я посмотрел, как я могу настроить значения во время копирования, т. Е. Как я могу предоставить какое-то другое значение полю вместо значения поля исходного объекта. Кроме того, я добавил функцию игнорирования некоторых полей при копировании, для которых будет выбрано значение по умолчанию, определенное в модели.

После того, как копирование всех полей заработало, я посмотрел на оптимизацию запросов, которые были сделаны к базе данных. Я связал это с массовым копированием/клонированием.

Я сделал это, потому что копирование большинства полей не было дружественным к базе данных или не могло работать с bulk_create . Например, наиболее распространенный способ добавления файлов с использованием Content File object для FileField требовал вызова базы данных исключительно для этого поля.

У этого также была другая проблема, связанная с тем, что файл был сначала загружен в память на сервере. Я решил эту проблему, сделав вызов API копирования в Amazon S3 (это было то, что мы использовали для хранения файлов), чтобы скопировать файлы в S3 и просто вернуть нам путь к файлу. Если у нас есть путь к файлу нового файла, то мы можем рассматривать поле FileField как любое обычное поле CharField.

Наконец, когда утилита была готова, я исправил методы клонирования и копирования в классе моделей Django, чтобы эти методы теперь были доступны для всех моделей в проекте.

Проблемы, с которыми я столкнулся

Самой большой проблемой, с которой я столкнулся , было копирование таких полей, как FileField , ManyToManyField и TreeForeignKey . Написание действия копирования для них не было сложным, но когда мне пришлось взглянуть на минимизацию запроса к базе данных, это стало намного сложнее. Мне пришлось потратить много времени на мозговой штурм и прохождение кода этих полей, чтобы попытаться оптимизировать запросы.

Основные уроки

Самый большой урок из этого заключался в том, чтобы всегда иметь представление обо всех вариантах использования вашего проекта. Если бы я не потратил время на понимание и перечисление всех вариантов использования, мне пришлось бы продолжать добавлять материал каждый раз, когда добавлялось что-то новое. Я считаю, что чем больше изменений вы вносите в то, что должно было быть общим, тем больше вероятность появления в нем ошибок.

Советы и рекомендации

Мой совет кому – то-потратить достаточно времени на перо и бумагу, разрабатывая то, что вы собираетесь реализовать, каковы варианты использования и разрабатывая тестовые примеры для этого проекта. Всякий раз, когда вы начинаете что-то новое, мы хотим быстро перейти к кодированию, но наличие какой-то письменной работы только сделает кодирование более увлекательным и плавным.

Заключительные мысли и следующие шаги

Я не буду работать над этим в ближайшее время, потому что утилита клонирования завершена и может обрабатывать клонирование всех доступных полей.