Evgenii Legotckoi
Evgenii LegotckoiСәуір 24, 2019, 3:42 Т.Ж.

Django - Сабақ 045. Модельдерді бір қолданбадан екіншісіне жылжыту

Деректер үлгісін бір қолданбадан екіншісіне тасымалдаудың мүмкін жолдарының бірімен бөліскім келеді.

Деректер үлгісін тасымалдауға арналған бұл опция 100% жұмыс істемейтінін және Мазмұн түрін дұрыс орнату үшін кестелерді қосымша қолмен өңдеу қажет болуы мүмкін екенін бірден ескертемін. Кез келген осындай өзгертулер GenericForeignKey қатынастары үшін деректердің жоғалуына алып келетіндіктен.

Менің жағдайда GenericForeignKey пайдаланылмады, сондықтан мұндай мәселе болмады.


Бастапқы деректер

Мақаланың үлгісі бар ескі мақала мақаласы бар делік. Блог қосымшасын жасап, мақала үлгісін осы қолданбаға тасымалдауыңыз қажет. PostgreSQL дерекқорын пайдаланады.

Үлгіні жылжыту

  1. Дерекқордың резервтік көшірмесін жасаңыз (сақтық көшірме), сіз дерекқордың демпін жасай аласыз және әзірлеу серверінде осы дампта тәжірибе жасай аласыз.

  2. Article үлгі кодын article.models.py -дан blog.models.py -ге жылжытыңыз. Яғни, ескі үлгідегі кодты алып тастау керек.

  3. Ескі кесте атауын сақтау үшін Мақал үлгісіндегі Meta класын өзгертіңіз. Бұл жағдайда article_artilce болды.

Мета класы:
db_table = 'article_article'
  1. Жоба бойынша деректер үлгілеріне барлық сілтемелерді өзгертіңіз. Бұл барлық импортты және ForeignKey өзгертуді білдіреді.

  2. Келесі ретпен екі қолданба үшін тасымалдауларды жасаңыз.

python manage.py makemigrations блогы
python manage.py makemigrations мақаласы
  1. Көшіруді жалған режимде қолданыңыз. Бұл тасымалдауларды олар қолданылған кезде қосуға мүмкіндік береді, бірақ ешқандай өзгертулер енгізілмейді.
python manage.py көшіру --жалған

Осы кезде дерекқор ContentType арқылы өткізілген деректер үлгісі үшін жасалмаған мағынада осал болады.

  1. Мұны келесі қадамдар арқылы түзетуге болады. Енді біз кесте атын өзгертуіміз керек және мұны деректер үлгісінен db_table жою және жаңа қолданбаға жаңа тасымалдауды жасау және қолдану арқылы жасауға болады. Мазмұн түрі тасымалдауды қолданғанда автоматты түрде жасалады.
python manage.py makemigrations блогы
python manage.py көшіру

Шындығында, осы қадамдардан кейін деректер базасы жұмыс істейді және деректер сақталады. Бірақ дерекқорды орнату үшін сізге қосымша қадамдар қажет болуы мүмкін.

Дерекқорды тазалау және жаңарту

Өткізілген деректер үлгісі қайда және қалай пайдаланылғанына байланысты. Сізге біраз әрекет жасау қажет болуы мүмкін. Мысалы, GenericForeignKey үшін Content Type параметрін реттеу.

Менде ең қарапайым жағдай болды - бұл ескі Мазмұн түрін жою. Ол үшін дерекқорға қосылу керек және ескі үлгінің Мазмұн түріне сілтеме жасай алатын барлық кестелерден ақпаратты жою керек.

Мұндай кестелер болуы мүмкін:

  • auth_user_user_рұқсаттары
  • аутентификациялық_рұқсат
  • django_content_type
  • және т.б. тапсыру алдында ескі үлгілерді пайдалана алатын басқа модельдер

Мен дерекқорымдағы ескі мазмұн түрінің мысалын көрсетемін.

Тазалау процесі

  1. Дерекқорға қосылыңыз
sudo -u postgres psql
\c myprojectdb
  1. Қай идентификаторлардың бұрынғы мазмұн түрі бар екенін көру үшін django_content_type кестесін қарастырайық.
ТАҢДАУ * Django_content_type;

Кестені шығару

id | app_label | үлгі
----+------------------+-----------------------
1 | шоттар | пайдаланушы профилі
2 | білім | бөлім
3 | білім | мақала
4 | админ | логентрия
5 | аутентификация | рұқсат
6 | аутентификация | топ
7 | аутентификация | пайдаланушы
8 | мазмұн түрлері | мазмұн түрі
9 | сеанстар | сеанс
  1. Ескі идентификаторды тауып, біз оларды жоюға тырысамыз (мысалы, 50 және 51)
django_content_type FROM ИД 50 ЖӘНЕ 51 АРАСЫНДА ЖОЮ;
  1. Егер ол орындалмаса, идентификатор деректерінің қайда пайдаланылатынын табу керек. Қате олардың қай кестелерге қатысқанын көрсетеді. Менің жағдайда бұл auth_permission және auth_user_user_permissions болды.
* 50 ЖӘНЕ 51 АРАСЫНДА мазмұн_түрінің_идентификаторы болатын auth_permission FROM ТАҢДАҢЫЗ;

Кестені шығару

id | аты | content_type_id | код аты
-----+--------------------+----------------+----- -----------
154 | чатты қосуға болады | 50 | add_chat
155 | чатты өзгерте алады | 50 | өзгерту_чат
156 | чатты жоя алады | 50 | жою_чат
157 | Хабарды қосуға болады | 51 | қосу_хабарлама
158 | Хабарламаны өзгерте алады | 51 | өзгерту_хабарлама
159 | Хабарды жоя алады | 51 | жою_хабарлама
276 | Чатты көре алады | 50 | көру_чат
277 | Хабарды көре алады | 51 | көру_хабарламасы

Әрі қарай, auth_user_user_permissions ішінен қызығушылық идентификаторын іздеңіз

ТАҢДАУ * auth_user_user_permissions ҚАЙДА permission_id=154;

Кестені шығару

id | user_id | рұқсат_идентификаторы
-----+---------+---------------
102 | 2 | 154
  1. auth_user_user_permissions кестесінен ескі Мазмұн түрі үшін барлық рұқсаттарды жойыңыз.
auth_user_user_permissions ҚАЙДАН ЖОЮ permission_id=154;
  1. auth_permission кестесінен рұқсатты жойыңыз.
50 ЖӘНЕ 51 АРАСЫНДА мазмұн_түрінің_идентификаторы ЖОЮ;
  1. Мазмұн түрлерін жою.
django_content_type FROM ИД 50 ЖӘНЕ 51 АРАСЫНДА ЖОЮ;

Қорытынды

Осылайша, қызықты деректер үлгісін бір қолданбадан екіншісіне жылжытуға, сондай-ақ ескірген мазмұнның дерекқорын тазалауға болады. Дегенмен, оның тұтастығын бұзбау үшін деректер қорымен өте мұқият жұмыс істеу керек.

Django үшін Timeweb VDS-server ұсынамын.

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Ол саған ұнайды ма? Әлеуметтік желілерде бөлісіңіз!

Макар Карабасов
  • Шілде 1, 2019, 5:45 Т.Қ.

Дружище, ну подскажи. Совершенно не понял 7-й пункт. А именно, а что происходит с данными, которые в таблице? Или всё делалось, когда в таблице нет данных?

Дело в том, что у меня как раз похожая ситуация. Только нужно перенести три модели, в другое приложение. Понимаю, что всё начинается с одной. Но вот незадача. Все эти таблицы уже заполнены. И связь с этими данными уже достаточно прочная (по факту нужно перенесети каталог, из данных которого уже полно действующих заказов).

И вот мне не ясен такой момент. Вот была article_article. Я из META убираю строчку. Делаю makemigrations и migrate. Так и что происходит с таблицей? Она становиться новенькой, или просто переименовывается?

Я понимаю, что бэкапы и всё такое, но как-то честно сказать очково. Буду потом плясать с этим бэкапом.

Evgenii Legotckoi
  • Шілде 2, 2019, 3:05 Т.Ж.

Всё делалось, когда данные были в таблице. Сам очковал по полной, когда впервые так делал, раз на десять издевался над дампом на дев сервере, чтобы ничего не поломать.

Суть в том, что старая модель данных переносится в другое приложение, но с помощью db_table = 'article_article' старая таблица сохраняется.

Когда удаляется article_article то в миграции создаётся новое имя таблицы. То есть старая таблица переименовывается, а данные в ней сохраняются.

При этом в шаге 3 таблица условно была удалена из старого приложения, за счёт fake миграции. То есть информация о миграции добавилась, но при этом изменений не произошло.

А вот шаг 7 как раз переименовывает таблицу, чтобы она фактически лежала в новом приложении. Так что ДА - она переименовывается с сохранением данных.

Макар Карабасов
  • Шілде 2, 2019, 4:56 Т.Ж.

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

Evgenii Legotckoi
  • Шілде 2, 2019, 7:01 Т.Ж.

Сам долго колупал форумы, чтобы найти полноценное решение, как это сделать и ничего не поломать.

Иногда там ещё бывают циклические зависимости - вот это реально проблема. Но в итоге тоже нашёл решение через сброс всех миграций и создание одной initial миграции и применение её через fake. Подробнее в этой статье .

bernar92
  • Қар. 9, 2021, 12:46 Т.Ж.
  • (өңделген)

у меня была проблема что у меня в кубере автоматом миграция запускалась сделал так (как вариант решения, добовлял каждой миграции RunSQL):

operations = [
        migrations.RunSQL('''
            ALTER TABLE IF EXISTS credits_operatorcreditapplication RENAME TO operator_creditapplication;
            create table credits_operatorcreditapplication();

            delete from auth_group_permissions
            USING (select *
                   from auth_permission
                   join django_content_type dct on dct.id = auth_permission.content_type_id
            ) dct
            where dct.app_label='credits' and dct.model='operatorcreditapplication';

            DELETE FROM auth_permission
            USING django_content_type
            where django_content_type.app_label='credits' and django_content_type.model='operatorcreditapplication';

            DELETE FROM django_admin_log
            USING django_content_type
            where django_content_type.app_label='credits' and django_content_type.model='operatorcreditapplication';

            DELETE FROM django_content_type WHERE app_label='credits' and model='operatorcreditapplication';
        '''),
        migrations.DeleteModel(
            name='OperatorCreditApplication',
        ),
    ]



operations = [
        migrations.CreateModel(
            name='OperatorCreditApplication',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('created_at', models.DateTimeField(auto_now_add=True, db_index=True, verbose_name='Время создания')),
                ('changed_at', models.DateTimeField(auto_now=True, db_index=True, verbose_name='Время последнего изменения'))
            ],
            options={
                'verbose_name': '....',
                'verbose_name_plural': '...',
                'ordering': ('created_at'),
            },
        ),
        migrations.RunSQL('''
            DROP TABLE IF EXISTS scoring_operatorcreditapplication;
            ALTER TABLE IF EXISTS operator_creditapplication RENAME TO scoring_operatorcreditapplication;
        ''')

    ]

Пікірлер

Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
Кіріңіз немесе Тіркеліңіз
Г

C++ - Тест 001. Первая программа и типы данных

  • Нәтиже:66ұпай,
  • Бағалау ұпайлары-1
t

C++ - Тест 001. Первая программа и типы данных

  • Нәтиже:33ұпай,
  • Бағалау ұпайлары-10
t

Qt - Тест 001. Сигналы и слоты

  • Нәтиже:52ұпай,
  • Бағалау ұпайлары-4
Соңғы пікірлер
G
GoattRockҚыр. 3, 2024, 1:50 Т.Қ.
Linux жүйесінде файлдарды қалай көшіруге болады Задумывались когда-нибудь о том, как мы привыкли доверять свои вещи службам грузоперевозок? Сейчас такие услуги стали неотъемлемой частью нашей жизни, особенно когда речь идет о переездах между …
d
dblas5Шілде 5, 2024, 11:02 Т.Ж.
QML - Сабақ 016. SQLite деректер қоры және онымен QML Qt-та жұмыс істеу Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
k
kmssrАқп. 8, 2024, 6:43 Т.Қ.
Qt Linux - Сабақ 001. Linux астында Autorun Qt қолданбасы как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
АК
Анатолий КононенкоАқп. 5, 2024, 1:50 Т.Ж.
Qt WinAPI - Сабақ 007. Qt ішінде ICMP Ping арқылы жұмыс істеу Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
Енді форумда талқылаңыз
Evgenii Legotckoi
Evgenii LegotckoiМаусым 24, 2024, 3:11 Т.Қ.
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
F
FynjyШілде 22, 2024, 4:15 Т.Ж.
при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …
BlinCT
BlinCTМаусым 25, 2024, 1 Т.Ж.
Нарисовать кривую в qml Всем привет. Имеется Лист листов с тосками, точки получаны интерполяцией Лагранжа. Вопрос, как этими точками нарисовать кривую? ChartView отпадает сразу, в qt6.7 появился новый элемент…
BlinCT
BlinCTМамыр 5, 2024, 5:46 Т.Ж.
Написать свой GraphsView Всем привет. В Qt есть давольно старый обьект дял работы с графиками ChartsView и есть в 6.7 новый но очень сырой и со слабым функционалом GraphsView. По этой причине я хочу написать х…
Evgenii Legotckoi
Evgenii LegotckoiМамыр 2, 2024, 2:07 Т.Қ.
Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Добрый день. По моему мнению - да, но то, что будет касаться вызовов к функционалу Андроида, может создать огромные трудности.

Бізді әлеуметтік желілерде бақылаңыз