From b4e0bf734830059960038187698e7f08bc291cc1 Mon Sep 17 00:00:00 2001 From: "Tomas \"Jethro\" Pokorny" Date: Tue, 30 Mar 2021 21:10:20 +0200 Subject: [PATCH 01/55] Migrace | reorganizace migraci MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Zatím neověřeně funkční reorganizace migrací, která odstraňuje situaci, kdy existovaly Node, ale neexistovalo django-polymorphic. Opravuje problém, kdy zmigrované problémy nemají jména (a asi i nic dalšího), možná přináší jiné problémy, nutné ověřit. --- ...1_squashed_0067_auto_20190814_0805.py.bak} | 0 .../0058_problem_to_uloha_tema_clanek.py | 41 +++++++++++-------- .../0065_treenode_polymorphic_ctype.py | 2 +- seminar/migrations/0066b_orgtextnode.py | 31 ++++++++++++++ seminar/migrations/0066c_reseninode.py | 29 +++++++++++++ seminar/migrations/0067_auto_20190814_0805.py | 2 +- seminar/migrations/0077_auto_20200318_2146.py | 2 +- seminar/migrations/0078_otistenereseninode.py | 27 ------------ seminar/migrations/0079_clanek_resitelsky.py | 2 +- .../0080_zruseni_claneknode_a_konferanode.py | 18 -------- seminar/migrations/0087_fix_polymorphism.py | 2 +- .../migrations/0088_perm_org_a_ucastnik.py | 2 +- seminar/migrations/0093_auto_20210330_2105.py | 28 +++++++++++++ 13 files changed, 119 insertions(+), 67 deletions(-) rename seminar/migrations/{0001_squashed_0067_auto_20190814_0805.py => 0001_squashed_0067_auto_20190814_0805.py.bak} (100%) create mode 100644 seminar/migrations/0066b_orgtextnode.py create mode 100644 seminar/migrations/0066c_reseninode.py delete mode 100644 seminar/migrations/0078_otistenereseninode.py create mode 100644 seminar/migrations/0093_auto_20210330_2105.py diff --git a/seminar/migrations/0001_squashed_0067_auto_20190814_0805.py b/seminar/migrations/0001_squashed_0067_auto_20190814_0805.py.bak similarity index 100% rename from seminar/migrations/0001_squashed_0067_auto_20190814_0805.py rename to seminar/migrations/0001_squashed_0067_auto_20190814_0805.py.bak diff --git a/seminar/migrations/0058_problem_to_uloha_tema_clanek.py b/seminar/migrations/0058_problem_to_uloha_tema_clanek.py index 7d651edb..ebd2d6fb 100644 --- a/seminar/migrations/0058_problem_to_uloha_tema_clanek.py +++ b/seminar/migrations/0058_problem_to_uloha_tema_clanek.py @@ -2,9 +2,10 @@ # Generated by Django 1.11.20 on 2019-05-17 17:44 from __future__ import unicode_literals -from django.db import migrations +from django.db import migrations, models from django.db.models import Q +import django.db.models.deletion def poskladej_strom(apps, rodic, *texty): Text = apps.get_model('seminar', 'Text') @@ -31,6 +32,13 @@ def poskladej_strom(apps, rodic, *texty): tn.succ = textnode tn.save() tn = tn.succ +def problem_to_polymorphic_Problem(apps,schema_editor): + Problem = apps.get_model('seminar', 'Problem') + ContentType = apps.get_model('contenttypes', 'ContentType') + + new_ct = ContentType.objects.get_for_model(Problem) + Problem.objects.filter(polymorphic_ctype__isnull=True).update(polymorphic_ctype=new_ct) + def uloha_to_Uloha(apps,schema_editor): Problem = apps.get_model('seminar', 'Problem') @@ -41,23 +49,24 @@ def uloha_to_Uloha(apps,schema_editor): TextNode = apps.get_model('seminar', 'TextNode') ulohy = Problem.objects.filter(typ = 'uloha') - for uold in ulohy: + for uold in ulohy[1:]: unew = Uloha.objects.create( - problem_ptr = uold, # Zakomentované fieldy by se už měly nacházet v příslušném problému - #nazev = uold.nazev, - #stav = uold.stav, - #zamereni = uold.zamereni, - #poznamka = uold.poznamka, - #autor = uold.autor, - #kod = uold.kod, + nazev = uold.nazev, + stav = uold.stav, + zamereni = uold.zamereni, + poznamka = uold.poznamka, + autor = uold.autor, + kod = uold.kod, cislo_zadani = uold.cislo_zadani_old, cislo_reseni = uold.cislo_reseni_old, max_body = uold.body, - #vytvoreno = uold.vytvoreno, + vytvoreno = uold.vytvoreno, ) -# unew.opravovatele.add(*uold.opravovatele.all()) unew.save() + unew.opravovatele.add(*uold.opravovatele.all()) + + return # Nody: zadani_node = UlohaZadaniNode.objects.create(uloha = unew) @@ -94,7 +103,7 @@ def clanek_to_Clanek(apps,schema_editor): raise ValueError("Různá čísla zadání a řešení u článku! (Článek: {})".format(cl.nazev)) clnew = Clanek.objects.create( - problem_ptr = cl, + problem_ptr_id = cl.id, # Problém by nemělo být potřeba upravovat cislo = cislo, # Body ignorujeme, protože už jsou v hodnocení @@ -149,13 +158,13 @@ def tema_to_Tema(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('seminar', '0057_reseni_to_reseni_hodnoceni'), + ('seminar', '0087_fix_polymorphism'), ] operations = [ # ashes to Ashes, dust to Dust.... migrations.RunPython(uloha_to_Uloha, migrations.RunPython.noop), - migrations.RunPython(tema_to_Tema, migrations.RunPython.noop), - migrations.RunPython(clanek_to_Clanek, migrations.RunPython.noop), - migrations.RunPython(konfery_rucne, migrations.RunPython.noop), + # migrations.RunPython(tema_to_Tema, migrations.RunPython.noop), + # migrations.RunPython(clanek_to_Clanek, migrations.RunPython.noop), + # migrations.RunPython(konfery_rucne, migrations.RunPython.noop), ] diff --git a/seminar/migrations/0065_treenode_polymorphic_ctype.py b/seminar/migrations/0065_treenode_polymorphic_ctype.py index cb65d8f1..88917d77 100644 --- a/seminar/migrations/0065_treenode_polymorphic_ctype.py +++ b/seminar/migrations/0065_treenode_polymorphic_ctype.py @@ -18,7 +18,7 @@ class Migration(migrations.Migration): dependencies = [ ('contenttypes', '0002_remove_content_type_name'), - ('seminar', '0064_auto_20190610_2358'), + ('seminar', '0057_reseni_to_reseni_hodnoceni'), ] operations = [ diff --git a/seminar/migrations/0066b_orgtextnode.py b/seminar/migrations/0066b_orgtextnode.py new file mode 100644 index 00000000..ecf509bb --- /dev/null +++ b/seminar/migrations/0066b_orgtextnode.py @@ -0,0 +1,31 @@ + +# Generated by Django 2.2.4 on 2019-08-13 19:45 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('seminar', '0066_problem_polymorphic_ctype'), + ] + + operations = [ + migrations.CreateModel( + name='OrgTextNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('org_verejny', models.BooleanField(default=True, help_text='Pokud ano, bude org pod článkem podepsaný', verbose_name='Org je veřejný?')), + ('organizator', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='seminar.Organizator', verbose_name='Organizátor')), + ], + options={ + 'verbose_name': 'Organizátorský článek (Node)', + 'verbose_name_plural': 'Organizátorské články (Node)', + 'db_table': 'seminar_nodes_orgtextnode', + }, + bases=('seminar.treenode',), + ), + + ] diff --git a/seminar/migrations/0066c_reseninode.py b/seminar/migrations/0066c_reseninode.py new file mode 100644 index 00000000..ae3e5a4e --- /dev/null +++ b/seminar/migrations/0066c_reseninode.py @@ -0,0 +1,29 @@ +# Generated by Django 2.2.4 on 2019-08-13 19:45 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('seminar', '0066b_orgtextnode'), + ] + + operations = [ + migrations.CreateModel( + name='ReseniNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('reseni', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Reseni', verbose_name='reseni')), + ], + options={ + 'verbose_name': 'Otištěné řešení (Node)', + 'verbose_name_plural': 'Otištěná řešení (Node)', + 'db_table': 'seminar_nodes_otistene_reseni', + }, + bases=('seminar.treenode',), + ), + + ] diff --git a/seminar/migrations/0067_auto_20190814_0805.py b/seminar/migrations/0067_auto_20190814_0805.py index 8a72a659..04d333a0 100644 --- a/seminar/migrations/0067_auto_20190814_0805.py +++ b/seminar/migrations/0067_auto_20190814_0805.py @@ -6,7 +6,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('seminar', '0066_problem_polymorphic_ctype'), + ('seminar', '0064_auto_20190610_2358'), ] operations = [ diff --git a/seminar/migrations/0077_auto_20200318_2146.py b/seminar/migrations/0077_auto_20200318_2146.py index 50053d9c..cc0e8c15 100644 --- a/seminar/migrations/0077_auto_20200318_2146.py +++ b/seminar/migrations/0077_auto_20200318_2146.py @@ -7,7 +7,7 @@ import django.db.models.deletion class Migration(migrations.Migration): dependencies = [ - ('seminar', '0076_auto_20200228_2013'), + ('seminar', '0066c_reseninode'), ] operations = [ diff --git a/seminar/migrations/0078_otistenereseninode.py b/seminar/migrations/0078_otistenereseninode.py deleted file mode 100644 index 2f426a17..00000000 --- a/seminar/migrations/0078_otistenereseninode.py +++ /dev/null @@ -1,27 +0,0 @@ -# Generated by Django 2.2.9 on 2020-03-18 23:59 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0077_auto_20200318_2146'), - ] - - operations = [ - migrations.CreateModel( - name='OtisteneReseniNode', - fields=[ - ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), - ('reseni', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Reseni', verbose_name='reseni')), - ], - options={ - 'verbose_name': 'Otištěné řešení (Node)', - 'verbose_name_plural': 'Otištěná řešení (Node)', - 'db_table': 'seminar_nodes_otistene_reseni', - }, - bases=('seminar.treenode',), - ), - ] diff --git a/seminar/migrations/0079_clanek_resitelsky.py b/seminar/migrations/0079_clanek_resitelsky.py index f41cdc51..88ad06eb 100644 --- a/seminar/migrations/0079_clanek_resitelsky.py +++ b/seminar/migrations/0079_clanek_resitelsky.py @@ -6,7 +6,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('seminar', '0078_otistenereseninode'), + ('seminar', '0076_auto_20200228_2013'), ] operations = [ diff --git a/seminar/migrations/0080_zruseni_claneknode_a_konferanode.py b/seminar/migrations/0080_zruseni_claneknode_a_konferanode.py index 34c22249..ddf3cc8e 100644 --- a/seminar/migrations/0080_zruseni_claneknode_a_konferanode.py +++ b/seminar/migrations/0080_zruseni_claneknode_a_konferanode.py @@ -31,28 +31,10 @@ class Migration(migrations.Migration): model_name='konfera', name='ucastnici', ), - migrations.CreateModel( - name='OrgTextNode', - fields=[ - ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), - ('org_verejny', models.BooleanField(default=True, help_text='Pokud ano, bude org pod článkem podepsaný', verbose_name='Org je veřejný?')), - ('organizator', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='seminar.Organizator', verbose_name='Organizátor')), - ], - options={ - 'verbose_name': 'Organizátorský článek (Node)', - 'verbose_name_plural': 'Organizátorské články (Node)', - 'db_table': 'seminar_nodes_orgtextnode', - }, - bases=('seminar.treenode',), - ), migrations.RemoveField( model_name='konfera', name='id', ), - migrations.RenameModel( - old_name='OtisteneReseniNode', - new_name='ReseniNode', - ), migrations.RemoveField( model_name='clanek', name='cislo', diff --git a/seminar/migrations/0087_fix_polymorphism.py b/seminar/migrations/0087_fix_polymorphism.py index 40ce9adf..e7852c42 100644 --- a/seminar/migrations/0087_fix_polymorphism.py +++ b/seminar/migrations/0087_fix_polymorphism.py @@ -41,7 +41,7 @@ def fix_problem(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('seminar', '0086_auto_20200819_0959'), + ('seminar', '0077_auto_20200318_2146'), ] operations = [ migrations.RunPython(fix_treenode, migrations.RunPython.noop), diff --git a/seminar/migrations/0088_perm_org_a_ucastnik.py b/seminar/migrations/0088_perm_org_a_ucastnik.py index ca6190dd..febcf141 100644 --- a/seminar/migrations/0088_perm_org_a_ucastnik.py +++ b/seminar/migrations/0088_perm_org_a_ucastnik.py @@ -27,7 +27,7 @@ def add_perms(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('seminar', '0087_fix_polymorphism'), + ('seminar', '0086_auto_20200819_0959'), ] operations = [ diff --git a/seminar/migrations/0093_auto_20210330_2105.py b/seminar/migrations/0093_auto_20210330_2105.py new file mode 100644 index 00000000..06132eca --- /dev/null +++ b/seminar/migrations/0093_auto_20210330_2105.py @@ -0,0 +1,28 @@ +# Generated by Django 2.2.12 on 2021-03-30 19:05 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0092_auto_20210309_2049'), + ] + + operations = [ + migrations.DeleteModel( + name='VysledkyCelkemKCislu', + ), + migrations.DeleteModel( + name='VysledkyKCislu', + ), + migrations.DeleteModel( + name='VysledkyKCisluOdjakziva', + ), + migrations.DeleteModel( + name='VysledkyKCisluZaRocnik', + ), + migrations.DeleteModel( + name='VysledkyZaCislo', + ), + ] From d15e97447e8bde95e520c1ea2989036ee5623b41 Mon Sep 17 00:00:00 2001 From: Tomas 'Jethro' Pokorny Date: Tue, 1 Jun 2021 21:30:54 +0200 Subject: [PATCH 02/55] Pridan nastroj na kontrolu spravnosti migraci. --- db_compare.py | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 db_compare.py diff --git a/db_compare.py b/db_compare.py new file mode 100644 index 00000000..e21a860b --- /dev/null +++ b/db_compare.py @@ -0,0 +1,58 @@ +#!/usr/bin/python3 + +import psycopg2 +import psycopg2.extras + +OLD_DB = "mam_old" +NEW_DB = "mamweb" + +oldconn = psycopg2.connect(f"dbname={OLD_DB}") +newconn = psycopg2.connect(f"dbname={NEW_DB}") + +oldcur = oldconn.cursor(cursor_factory=psycopg2.extras.DictCursor) +newcur = newconn.cursor(cursor_factory=psycopg2.extras.DictCursor) + + +# Uses global variables oldcur, newcur! +def execute_simple(old_query, new_query=None): + if new_query is None: + new_query = old_query + + oldcur.execute(old_query) + newcur.execute(new_query) + + if oldcur.rowcount != newcur.rowcount: + raise ValueError(f"Queries '{old_query}' and '{new_query}' returned different number of rows ({oldcur.rowcount} and {newcur.rowcount})") + + return(oldcur.fetchall(), newcur.fetchall()) + +def check_same(old_row, new_row, old_fields, new_fields=None): + if type(old_fields) != list: + old_fields = [old_fields] + + if new_fields is None: + new_fields = old_fields + + fields = zip(old_fields, new_fields) + + for old_field, new_field in fields: + if old_row[old_field] == new_row[new_field]: + continue + raise ValueError(f"Fields '{old_field}' and '{new_field}' differs for rows '{old_row}' and '{new_row}'") + return True + + + +def check_skola(): + old_query = "SELECT * FROM seminar_skoly ORDER BY id" + new_query = old_query + + old_res, new_res = execute_simple(old_query,new_query) + + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n,['id','aesop_id','izo','nazev','kratky_nazev','ulice','mesto','psc','stat','je_zs','je_ss','poznamka']) + +check_skola() + From 4c99bb88dbc8c30f3c0bfbaa4d8da5a8cce9c9c9 Mon Sep 17 00:00:00 2001 From: Tomas 'Jethro' Pokorny Date: Tue, 1 Jun 2021 22:58:13 +0200 Subject: [PATCH 03/55] Pridany kontroly migraci. --- db_compare.py | 105 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 101 insertions(+), 4 deletions(-) diff --git a/db_compare.py b/db_compare.py index e21a860b..705930da 100644 --- a/db_compare.py +++ b/db_compare.py @@ -41,18 +41,115 @@ def check_same(old_row, new_row, old_fields, new_fields=None): raise ValueError(f"Fields '{old_field}' and '{new_field}' differs for rows '{old_row}' and '{new_row}'") return True +def get_user_id_for_org_id(org_id): + query = """SELECT auth_user.id FROM auth_user + INNER JOIN seminar_osoby ON seminar_osoby.user_id = auth_user.id + INNER JOIN seminar_organizator ON seminar_organizator.osoba_id = seminar_osoby.id + WHERE seminar_organizator.id = %s """ + + newcur.execute(query,(org_id,)) + return newcur.fetchone()['id'] + + def check_skola(): old_query = "SELECT * FROM seminar_skoly ORDER BY id" - new_query = old_query - - old_res, new_res = execute_simple(old_query,new_query) + old_res, new_res = execute_simple(old_query) res = zip(old_res,new_res) for o,n in res: check_same(o,n,['id','aesop_id','izo','nazev','kratky_nazev','ulice','mesto','psc','stat','je_zs','je_ss','poznamka']) -check_skola() +def check_rocnik(): + old_query = "SELECT * FROM seminar_rocniky ORDER BY id" + + old_res, new_res = execute_simple(old_query) + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n,['id','prvni_rok', 'rocnik', 'exportovat']) + +def check_cislo(): + old_query = "SELECT * FROM seminar_cisla ORDER BY id" + + old_res, new_res = execute_simple(old_query) + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n, ['id','rocnik_id','cislo', 'datum_vydani','datum_deadline','verejne','poznamka','pdf'], + ['id','rocnik_id','poradi','datum_vydani','datum_deadline','verejne','poznamka','pdf']) + +def check_priloha_reseni(): + old_query = "SELECT * FROM seminar_priloha_reseni" + + old_res, new_res = execute_simple(old_query) + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n, ['id','reseni_id', 'timestamp', 'soubor', 'poznamka'], + ['id','reseni_id', 'vytvoreno', 'soubor', 'poznamka']) + +def check_soustredeni(): + old_query = "SELECT * FROM seminar_soustredeni ORDER BY id" + + old_res, new_res = execute_simple(old_query) + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n,['id','rocnik_id','datum_zacatku','datum_konce','verejne','misto','text','typ','exportovat']) + #Kontrola ucasnici, organizatori v samostatnych funkcich + +def check_soustredeni_ucastnici(): + old_query = "SELECT * FROM seminar_soustredeni_ucastnici ORDER BY id" + old_res, new_res = execute_simple(old_query) + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n,['id','resitel_id','soustredeni_id','poznamka']) + +def check_soustredeni_organizatori(): + old_query = "SELECT * FROM seminar_soustredeni_organizatori ORDER BY id" + + old_res, new_res = execute_simple(old_query) + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n,['id','organizator_id','soustredeni_id','poznamka']) + +def check_nastaveni(): + old_query = "SELECT * FROM seminar_nastaveni ORDER BY id" + + old_res, new_res = execute_simple(old_query) + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n,['id','aktualni_cislo_id']) + +def check_novinky(): + old_query = "SELECT * FROM seminar_novinky ORDER BY id" + + old_res, new_res = execute_simple(old_query) + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n,['id','datum','text','obrazek','zverejneno']) + if get_user_id_for_org_id(n['autor_id']) != o['autor_id']: + raise ValueError("Nesedi autori u novinek") + + + + + + +check_skola() +check_rocnik() +check_cislo() +check_priloha_reseni() +check_soustredeni() +check_soustredeni_ucastnici() +check_soustredeni_organizatori() +check_nastaveni() +check_novinky() From a0a7f5d33217cd2ad32b7eea20237707201b8bbe Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Tue, 1 Jun 2021 23:07:30 +0200 Subject: [PATCH 04/55] =?UTF-8?q?Ty=20jednodu=C5=A1=C5=A1=C3=AD=20Pavlovy?= =?UTF-8?q?=20=C4=8D=C3=A1sti?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db_compare.py | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/db_compare.py b/db_compare.py index e21a860b..29775d3a 100644 --- a/db_compare.py +++ b/db_compare.py @@ -54,5 +54,104 @@ def check_skola(): for o,n in res: check_same(o,n,['id','aesop_id','izo','nazev','kratky_nazev','ulice','mesto','psc','stat','je_zs','je_ss','poznamka']) +def check_resitel(): + old_query = 'SELECT * FROM seminar_resitele ORDER BY id' + new_query = 'SELECT * FROM seminar_resitele JOIN seminar_osoby ON seminar_resitele.osoba_id = seminar_osoby.id ORDER BY seminar_resitele.id' + + old_res, new_res = execute_simple(old_query,new_query) + + res = zip(old_res,new_res) + + fields_osoba = [ + 'jmeno', + 'prijmeni', + 'user', + 'pohlavi_muz', + 'email', + 'telefon', + 'datum_narozeni', + 'datum_souhlasu_udaje', + 'datum_souhlasu_zasilani', + 'datum_prihlaseni', + 'ulice', + 'mesto', + 'psc', + 'stat', + ] + fields_keep = [ + 'id', + 'skola_id', + 'rok_maturity', + 'zasilat', + 'poznamka', + ] + fields_old = fields_keep+fields_osoba + fields_new = fields_keep + ['seminar_osoby.'+f for f in fields_osoba] + for o,n in res: + check_same(o,n,fields_old, fields_new) + +def check_reseni(): + old_query = 'SELECT * FROM seminar_reseni ORDER BY id' + new_query = 'SELECT * FROM seminar_reseni JOIN seminar_hodnoceni AS hodnoceni ON hodnoceni_id = hodnoceni.id ORDER BY id' + + same_fields = ['id', 'forma', 'poznamka'] + renamed_fields = [('timestamp', 'cas_doruceni'), + # Also moved fields + ('problem_id', 'hodnoceni.problem_id'), + ('body', 'hodnoceni.body'), + ('cislo_body_id', 'hodnoceni.cislo_body_id'), + ] + old_fields = same_fields + [f[0] for f in renamed_fields] + new_fields = same_fields + [f[1] for f in renamed_fields] + + old_res, new_res = execute_simple(old_query,new_query) + + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n,old_fields, new_fields) + + # Řešitelé jsou nově m2m, takže je musíme dohledat + old_query = 'SELECT id, resitel_id FROM seminar_reseni ORDER BY id' + new_query = 'SELECT reseni_id, resitel_id FROM seminar_reseni_resitele ORDER BY reseni_id' + + oldcur = oldconn.cursor() + old_results = oldcur.execute(old_query).fetchall() + newcur = newconn.cursor() + new_results = newcur.execute(old_query).fetchall() + + for oldr in old_results: + if oldr not in new_results: + raise ValueError(f'Pair {oldr} not found in new db.') + +def check_organizator(): + old_query = 'SELECT * FROM seminar_organizatori ORDER BY id' + new_query = 'SELECT * FROM seminar_organizatori JOIN seminar_osoby AS osoba ON osoba_id = osoba.id JOIN auth_user AS user ON osoba.user_id = user.id ORDER BY id' + + same_fields = ['studuje', 'strucny_popis_organizatora'] + renamed_fields = [ + ('user_id', 'user.id'), + ('prezdivka', 'osoba.prezdivka'), + ('foto', 'osoba.foto'), + ('foto_male', 'osoba.foto_male'), + ] + old_fields = same_fields + [f[0] for f in renamed_fields] + new_fields = same_fields + [f[1] for f in renamed_fields] + + old_res, new_res = execute_simple(old_query,new_query) + res = zip(old_res, new_res) + for o,n in res: + check_same(o,n,old_fields, new_fields) + # organizuje od, do: + if o.organizuje_od_roku != n.organizuje_od.year: + raise ValueError(f'Not matching organizuje_od for org id={o.id}: old {o.organizuje_od_roku}, new {n.organizuje_od}') + if o.organizuje_do_roku != n.organizuje_do.year: + raise ValueError(f'Not matching organizuje_do for org id={o.id}: old {o.organizuje_do_roku}, new {n.organizuje_do}') + + + check_skola() +check_resitel() +check_reseni() +check_organizator() From 49cc21b040ed46182a555af47460798d9c076d2e Mon Sep 17 00:00:00 2001 From: Tomas 'Jethro' Pokorny Date: Tue, 1 Jun 2021 23:29:04 +0200 Subject: [PATCH 05/55] Pridana kontrola migraci pohadky. --- db_compare.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/db_compare.py b/db_compare.py index 705930da..fee8af35 100644 --- a/db_compare.py +++ b/db_compare.py @@ -38,7 +38,7 @@ def check_same(old_row, new_row, old_fields, new_fields=None): for old_field, new_field in fields: if old_row[old_field] == new_row[new_field]: continue - raise ValueError(f"Fields '{old_field}' and '{new_field}' differs for rows '{old_row}' and '{new_row}'") + raise ValueError(f"Fields '{old_field}' and '{new_field}' differs for rows \n'{old_row}' and \n'{new_row}'") return True def get_user_id_for_org_id(org_id): @@ -139,6 +139,26 @@ def check_novinky(): if get_user_id_for_org_id(n['autor_id']) != o['autor_id']: raise ValueError("Nesedi autori u novinek") +def check_pohadka(): + old_query = "SELECT * FROM seminar_pohadky ORDER BY id" + new_query = """SELECT sp.id AS id, sp.autor_id AS autor_id, sp.vytvoreno AS vytvoreno, snp.treenode_ptr_id AS treenode_ptr_id, st.na_web AS text + FROM seminar_pohadky AS sp + INNER JOIN seminar_nodes_pohadka AS snp ON sp.id = snp.pohadka_id + INNER JOIN seminar_nodes_treenode AS snt ON snt.id = snp.treenode_ptr_id + INNER JOIN seminar_nodes_obsah AS sno ON sno.treenode_ptr_id = snt.first_child_id + INNER JOIN seminar_texty AS st ON sno.text_id = st.id + + ORDER BY sp.id""" + + old_res, new_res = execute_simple(old_query,new_query) + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n,['id','timestamp','text'],['id','vytvoreno','text']) + if o['autor_id'] is not None: + if get_user_id_for_org_id(n['autor_id']) != o['autor_id']: + raise ValueError("Nesedi autori u pohadky") + @@ -153,3 +173,4 @@ check_soustredeni_ucastnici() check_soustredeni_organizatori() check_nastaveni() check_novinky() +check_pohadka() From f65ffefb3b2f9cbc545249bf38001e9894b09113 Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Tue, 1 Jun 2021 23:30:41 +0200 Subject: [PATCH 06/55] =?UTF-8?q?J=C3=A1dro=20ov=C4=9B=C5=99en=C3=AD=20pro?= =?UTF-8?q?bl=C3=A9m=C5=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db_compare.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/db_compare.py b/db_compare.py index 6e594d5f..8ee613e6 100644 --- a/db_compare.py +++ b/db_compare.py @@ -234,6 +234,42 @@ def check_novinky(): raise ValueError("Nesedi autori u novinek") +# Problémy jsou rozdělené podle typů: +def check_uloha(): + raise NotImplementedError() +def check_tema(): + raise NotImplementedError() +def check_konfera(): + old_query = "SELECT * FROM seminar_problemy WHERE typ = 'konfera'" + new_query = "SELECT * FROM seminar_konfera JOIN seminar_problemy as problem ON problem_ptr_id = problem.id" + + oldcur.execute(old_query) + newcur.execute(new_query) + + if oldcur.rowcount != 0 or newcur.rowcount != 0: + raise ValueError('There exists a Konfera!') + +def check_org_clanek(): + old_query = "SELECT * FROM seminar_problemy WHERE typ = 'org-clanek'" + + oldcur.execute(old_query) + + if oldcur.rowcount != 0: + raise ValueError('There exists a Org-clanek!') + +def check_res_clanek(): + raise NotImplementedError() + +def check_untyped_problem(): + old_query = "SELECT * FROM seminar_problemy WHERE typ NOT IN ('uloha', 'tema', 'serial', 'konfera', 'org-clanek', 'res-clanek')" + + oldcur.execute(old_query) + + if oldcur.rowcount != 0: + raise ValueError('There exists a Problem without type!') + + + check_skola() check_resitel() check_reseni() @@ -246,3 +282,10 @@ check_soustredeni_ucastnici() check_soustredeni_organizatori() check_nastaveni() check_novinky() + +check_uloha() +check_tema() +check_konfera() +check_org_clanek() +check_res_clanek() +check_untyped_problem() From 96404abd200e8ad829d7a27937616775ba194d07 Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Wed, 2 Jun 2021 02:12:00 +0200 Subject: [PATCH 07/55] =?UTF-8?q?Implementace=20zbytku=20probl=C3=A9m?= =?UTF-8?q?=C5=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To, co zbývá, je označené buď jako TODO, nebo jako FIXME. --- db_compare.py | 121 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 115 insertions(+), 6 deletions(-) diff --git a/db_compare.py b/db_compare.py index f6797916..112d4276 100644 --- a/db_compare.py +++ b/db_compare.py @@ -104,7 +104,6 @@ def check_reseni(): same_fields = ['id', 'forma', 'poznamka'] renamed_fields = [('timestamp', 'cas_doruceni'), - # Also moved fields ('problem_id', 'hodnoceni.problem_id'), ('body', 'hodnoceni.body'), ('cislo_body_id', 'hodnoceni.cislo_body_id'), @@ -126,11 +125,11 @@ def check_reseni(): oldcur = oldconn.cursor() old_results = oldcur.execute(old_query).fetchall() newcur = newconn.cursor() - new_results = newcur.execute(old_query).fetchall() + new_results = newcur.execute(new_query).fetchall() for oldr in old_results: if oldr not in new_results: - raise ValueError(f'Pair {oldr} not found in new db.') + raise ValueError(f'Reseni pair {oldr} not found in new db.') def check_organizator(): old_query = 'SELECT * FROM seminar_organizatori ORDER BY id' @@ -255,10 +254,106 @@ def check_pohadka(): # Problémy jsou rozdělené podle typů: +def check_problem_common(): + query = "SELECT * FROM seminar_problemy ORDER BY id" + + same_fields = ['id', 'nazev', 'stav', 'autor', 'kod'] + renamed_fields = [ + ('text_org', 'poznamka'), + ('timestamp', 'vytvoreno'), + ] + old_fields = same_fields + [f[0] for f in renamed_fields] + new_fields = same_fields + [f[1] for f in renamed_fields] + + old_res, new_res = execute_simple(query) + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n, old_fields, new_fields) + + # Opravovatelé + old_query = "SELECT id, opravovatel_id FROM seminar_problemy" + new_query = "SELECT problem_id, opravovatel_id FROM seminar_problemy_opravovatele" + + # Simple cursors + oldcur = oldconn.cursor() + old_results = oldcur.execute(old_query).fetchall() + newcur = newconn.cursor() + new_results = newcur.execute(new_query).fetchall() + + for oldr in old_results: + if oldr not in new_results: + raise ValueError(f'Opravovatel pair {oldr} not found in new db.') + + # FIXME: Zaměření? + + def check_uloha(): - raise NotImplementedError() + old_query = "SELECT * FROM seminar_problemy WHERE typ = 'uloha' ORDER BY id" + new_query = """SELECT cislo_zadani, cislo_reseni, problem_ptr_id, max_body, uzt.na_web AS text_zadani, uvt.na_web AS text_reseni + FROM seminar_ulohy + -- Problém: + JOIN seminar_problemy AS problem ON problem_ptr_id = problem.id + -- Text zadání: + INNER JOIN seminar_nodes_uloha_zadani AS uzn ON id = uzn.uloha_id + INNER JOIN seminar_nodes_treenode AS uztn ON uztn.id = uzn.treenode_ptr_id + INNER JOIN seminar_nodes_obsah AS uzo ON uzo.treenode_ptr_id = uztn.first_child_id + INNER JOIN seminar_texty AS uzt ON uzo.text_id = uzt.id + -- Text vzoráku: + INNER JOIN seminar_nodes_uloha_zadani AS uvn ON id = uvn.uloha_id + INNER JOIN seminar_nodes_treenode AS uvtn ON uvtn.id = uvn.treenode_ptr_id + INNER JOIN seminar_nodes_obsah AS uvo ON uvo.treenode_ptr_id = uvtn.first_child_id + INNER JOIN seminar_texty AS uvt ON uvo.text_id = uvt.id + + ORDER BY problem_ptr_id""" + + same_fields = ['cislo_zadani', 'cislo_reseni', 'text_zadani', 'text_reseni'] + renamed_fields = [ + ('id', 'problem_ptr_id'), + ('body', 'max_body'), + ] + old_fields = same_fields + [f[0] for f in renamed_fields] + new_fields = same_fields + [f[1] for f in renamed_fields] + + old_res, new_res = execute_simple(old_query, new_query) + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n, old_fields, new_fields) + # TODO: cislo_deadline + def check_tema(): - raise NotImplementedError() + old_query = "SELECT * FROM seminar_problemy WHERE typ IN ('tema', 'serial') ORDER BY id" + new_query = """SELECT tema_typ, zad_text.na_web as text_zadani, res_text.na_web as text_reseni + FROM seminar_temata + -- Problém: + JOIN seminar_problemy AS problem ON problem_ptr_id = problem.id + -- Text: + -- TvCNode má dva potomky, oba TextNode. První drží původní text zadání, druhý řešení. + INNER JOIN seminar_nodes_temavcisle as tvcn ON tvcn.tema_id = id + INNER JOIN seminar_nodes_treenode AS roottn ON tvcn.treenode_ptr_id = roottn.id + INNER JOIN seminar_nodes_treenode AS zad_tn ON roottn.first_child_id = zad_tn.id + INNER JOIN seminar_nodes_treenode AS res_tn ON zad_tn.succ_id = res_tn.id + INNER JOIN seminar_nodes_obsah AS zad_on ON zad_on.treenode_ptr_id = zad_tn.id + INNER JOIN seminar_nodes_obsah AS res_on ON res_on.treenode_ptr_id = res_tn.id + INNER JOIN seminar_texty as zad_text ON zad_on.text_id = zad_text.id + INNER JOIN seminar_texty as res_text ON res_on.text_id = res_text.id + + ORDER BY problem_ptr_id""" + same_fields = ['text_zadani', 'text_reseni'] + renamed_fields = [ + ('typ', 'tema_typ'), + ] + old_fields = same_fields + [f[0] for f in renamed_fields] + new_fields = same_fields + [f[1] for f in renamed_fields] + + old_res, new_res = execute_simple(old_query, new_query) + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n, old_fields, new_fields) + #TODO: Tema.rocnik + def check_konfera(): old_query = "SELECT * FROM seminar_problemy WHERE typ = 'konfera'" new_query = "SELECT * FROM seminar_konfera JOIN seminar_problemy as problem ON problem_ptr_id = problem.id" @@ -278,7 +373,20 @@ def check_org_clanek(): raise ValueError('There exists a Org-clanek!') def check_res_clanek(): - raise NotImplementedError() + old_query = "SELECT * FROM seminar_problemy WHERE typ = 'res-clanek' ORDER BY id" + new_query = "SELECT * FROM seminar_clanky JOIN seminar_problemy as problem ON problem_ptr_id = problem.id ORDER BY problem_ptr_id" + same_fields = [] + renamed_fields = [ + ] + old_fields = same_fields + [f[0] for f in renamed_fields] + new_fields = same_fields + [f[1] for f in renamed_fields] + + old_res, new_res = execute_simple(old_query, new_query) + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n, old_fields, new_fields) + # TODO: Cislo def check_untyped_problem(): old_query = "SELECT * FROM seminar_problemy WHERE typ NOT IN ('uloha', 'tema', 'serial', 'konfera', 'org-clanek', 'res-clanek')" @@ -304,6 +412,7 @@ check_nastaveni() check_novinky() check_pohadka() +check_problem_common() check_uloha() check_tema() check_konfera() From 3ffbe08e674254236d83c87001cde8d7c9a0131d Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Wed, 2 Jun 2021 02:26:24 +0200 Subject: [PATCH 08/55] =?UTF-8?q?Zru=C5=A1ena=20kontrola=20=C5=99e=C5=A1it?= =?UTF-8?q?elsk=C3=BDch=20=C4=8Dl=C3=A1nk=C5=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db_compare.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/db_compare.py b/db_compare.py index 112d4276..e58b6f11 100644 --- a/db_compare.py +++ b/db_compare.py @@ -373,20 +373,20 @@ def check_org_clanek(): raise ValueError('There exists a Org-clanek!') def check_res_clanek(): - old_query = "SELECT * FROM seminar_problemy WHERE typ = 'res-clanek' ORDER BY id" - new_query = "SELECT * FROM seminar_clanky JOIN seminar_problemy as problem ON problem_ptr_id = problem.id ORDER BY problem_ptr_id" - same_fields = [] - renamed_fields = [ - ] - old_fields = same_fields + [f[0] for f in renamed_fields] - new_fields = same_fields + [f[1] for f in renamed_fields] - - old_res, new_res = execute_simple(old_query, new_query) - res = zip(old_res,new_res) - - for o,n in res: - check_same(o,n, old_fields, new_fields) - # TODO: Cislo + return; # FIXME: Je vůbec co testovat? Ta tabulka obsahuje jen problem_ptr_id a cislo_id, které ale není nikde vyplněné. + #old_query = "SELECT * FROM seminar_problemy WHERE typ = 'res-clanek' ORDER BY id" + #new_query = "SELECT * FROM seminar_clanky JOIN seminar_problemy as problem ON problem_ptr_id = problem.id ORDER BY problem_ptr_id" + #same_fields = [] + #renamed_fields = [] + #old_fields = same_fields + [f[0] for f in renamed_fields] + #new_fields = same_fields + [f[1] for f in renamed_fields] + + #old_res, new_res = execute_simple(old_query, new_query) + #res = zip(old_res,new_res) + + #for o,n in res: + # check_same(o,n, old_fields, new_fields) + ## TODO: Cislo def check_untyped_problem(): old_query = "SELECT * FROM seminar_problemy WHERE typ NOT IN ('uloha', 'tema', 'serial', 'konfera', 'org-clanek', 'res-clanek')" From ac4b93cd52f6a2980618c431d207cfe110d74caf Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Wed, 2 Jun 2021 02:38:31 +0200 Subject: [PATCH 09/55] =?UTF-8?q?Oprava=20case,=20impl=20=C5=99e=C5=A1itel?= =?UTF-8?q?sk=C3=BDch=20=C4=8Dl=C3=A1nk=C5=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db_compare.py | 49 ++++++++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/db_compare.py b/db_compare.py index e58b6f11..6c13883b 100644 --- a/db_compare.py +++ b/db_compare.py @@ -324,20 +324,20 @@ def check_uloha(): def check_tema(): old_query = "SELECT * FROM seminar_problemy WHERE typ IN ('tema', 'serial') ORDER BY id" - new_query = """SELECT tema_typ, zad_text.na_web as text_zadani, res_text.na_web as text_reseni + new_query = """SELECT tema_typ, zad_text.na_web AS text_zadani, res_text.na_web AS text_reseni FROM seminar_temata -- Problém: JOIN seminar_problemy AS problem ON problem_ptr_id = problem.id -- Text: -- TvCNode má dva potomky, oba TextNode. První drží původní text zadání, druhý řešení. - INNER JOIN seminar_nodes_temavcisle as tvcn ON tvcn.tema_id = id + INNER JOIN seminar_nodes_temavcisle AS tvcn ON tvcn.tema_id = id INNER JOIN seminar_nodes_treenode AS roottn ON tvcn.treenode_ptr_id = roottn.id INNER JOIN seminar_nodes_treenode AS zad_tn ON roottn.first_child_id = zad_tn.id INNER JOIN seminar_nodes_treenode AS res_tn ON zad_tn.succ_id = res_tn.id INNER JOIN seminar_nodes_obsah AS zad_on ON zad_on.treenode_ptr_id = zad_tn.id INNER JOIN seminar_nodes_obsah AS res_on ON res_on.treenode_ptr_id = res_tn.id - INNER JOIN seminar_texty as zad_text ON zad_on.text_id = zad_text.id - INNER JOIN seminar_texty as res_text ON res_on.text_id = res_text.id + INNER JOIN seminar_texty AS zad_text ON zad_on.text_id = zad_text.id + INNER JOIN seminar_texty AS res_text ON res_on.text_id = res_text.id ORDER BY problem_ptr_id""" same_fields = ['text_zadani', 'text_reseni'] @@ -356,7 +356,7 @@ def check_tema(): def check_konfera(): old_query = "SELECT * FROM seminar_problemy WHERE typ = 'konfera'" - new_query = "SELECT * FROM seminar_konfera JOIN seminar_problemy as problem ON problem_ptr_id = problem.id" + new_query = "SELECT * FROM seminar_konfera JOIN seminar_problemy AS problem ON problem_ptr_id = problem.id" oldcur.execute(old_query) newcur.execute(new_query) @@ -373,20 +373,31 @@ def check_org_clanek(): raise ValueError('There exists a Org-clanek!') def check_res_clanek(): - return; # FIXME: Je vůbec co testovat? Ta tabulka obsahuje jen problem_ptr_id a cislo_id, které ale není nikde vyplněné. - #old_query = "SELECT * FROM seminar_problemy WHERE typ = 'res-clanek' ORDER BY id" - #new_query = "SELECT * FROM seminar_clanky JOIN seminar_problemy as problem ON problem_ptr_id = problem.id ORDER BY problem_ptr_id" - #same_fields = [] - #renamed_fields = [] - #old_fields = same_fields + [f[0] for f in renamed_fields] - #new_fields = same_fields + [f[1] for f in renamed_fields] - - #old_res, new_res = execute_simple(old_query, new_query) - #res = zip(old_res,new_res) - - #for o,n in res: - # check_same(o,n, old_fields, new_fields) - ## TODO: Cislo + # Dva(!) články mají text (zadání), který se má zachovat. + old_query = "SELECT * FROM seminar_problemy WHERE typ = 'res-clanek' ORDER BY id" + new_query = """SELECT cislo_id, text.na_web AS text_zadani + FROM seminar_clanky + JOIN seminar_problemy AS problem ON problem_ptr_id = problem.id + INNER JOIN seminar_hodnoceni AS hodn ON problem.id = hodn.problem_id + INNER JOIN seminar_reseni AS rese ON rese.id = hodn.reseni_id + INNER JOIN seminar_nodes_reseni AS resnode ON resnode.reseni_id = rese.id + INNER JOIN seminar_nodes_treenode AS tn ON resnode.treenode_ptr_id = tn.id + INNER JOIN seminar_nodes_obsah AS on ON on.treenode_ptr_id = tn.first_child_id + INNER JOIN seminar_texty AS text ON text.id = on.text_id + + ORDER BY problem_ptr_id""" + same_fields = ['text_zadani'] + renamed_fields = [ + ('cislo_zadani_id', 'cislo_id'), + ] + old_fields = same_fields + [f[0] for f in renamed_fields] + new_fields = same_fields + [f[1] for f in renamed_fields] + + old_res, new_res = execute_simple(old_query, new_query) + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n, old_fields, new_fields) def check_untyped_problem(): old_query = "SELECT * FROM seminar_problemy WHERE typ NOT IN ('uloha', 'tema', 'serial', 'konfera', 'org-clanek', 'res-clanek')" From 86bc839f2ae851410dc997561780a0a9a4ce2d64 Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Wed, 2 Jun 2021 02:41:21 +0200 Subject: [PATCH 10/55] =?UTF-8?q?=C3=9Alohy=20hotovy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db_compare.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/db_compare.py b/db_compare.py index 6c13883b..a2775e9c 100644 --- a/db_compare.py +++ b/db_compare.py @@ -320,7 +320,9 @@ def check_uloha(): for o,n in res: check_same(o,n, old_fields, new_fields) - # TODO: cislo_deadline + # Datum deadline vypadá prázdně, tak to budeme předpokládat. + if n['datum_deadline'] is not None: + raise ValueError("Úloha má deadline.") def check_tema(): old_query = "SELECT * FROM seminar_problemy WHERE typ IN ('tema', 'serial') ORDER BY id" From 6c71f050d0d25693ca949ba11bbfbf1a1d11f271 Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Wed, 2 Jun 2021 02:59:27 +0200 Subject: [PATCH 11/55] =?UTF-8?q?T=C3=A9ma=20->=20ro=C4=8Dn=C3=ADk?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db_compare.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/db_compare.py b/db_compare.py index a2775e9c..683e2037 100644 --- a/db_compare.py +++ b/db_compare.py @@ -325,24 +325,31 @@ def check_uloha(): raise ValueError("Úloha má deadline.") def check_tema(): - old_query = "SELECT * FROM seminar_problemy WHERE typ IN ('tema', 'serial') ORDER BY id" - new_query = """SELECT tema_typ, zad_text.na_web AS text_zadani, res_text.na_web AS text_reseni + old_query = """SELECT text_zadani, text_reseni, typ, c.rocnik_id AS rocnik_id + FROM seminar_problemy + INNER JOIN seminar_cisla as c ON c.id = cislo_zadani_id + WHERE typ IN ('tema', 'serial') + ORDER BY id""" + new_query = """SELECT tema_typ, zad_text.na_web AS text_zadani, res_text.na_web AS text_reseni, rn.rocnik_id AS rocnik_id FROM seminar_temata -- Problém: JOIN seminar_problemy AS problem ON problem_ptr_id = problem.id -- Text: -- TvCNode má dva potomky, oba TextNode. První drží původní text zadání, druhý řešení. INNER JOIN seminar_nodes_temavcisle AS tvcn ON tvcn.tema_id = id - INNER JOIN seminar_nodes_treenode AS roottn ON tvcn.treenode_ptr_id = roottn.id - INNER JOIN seminar_nodes_treenode AS zad_tn ON roottn.first_child_id = zad_tn.id + INNER JOIN seminar_nodes_treenode AS ttn ON tvcn.treenode_ptr_id = ttn.id + INNER JOIN seminar_nodes_treenode AS zad_tn ON ttn.first_child_id = zad_tn.id INNER JOIN seminar_nodes_treenode AS res_tn ON zad_tn.succ_id = res_tn.id INNER JOIN seminar_nodes_obsah AS zad_on ON zad_on.treenode_ptr_id = zad_tn.id INNER JOIN seminar_nodes_obsah AS res_on ON res_on.treenode_ptr_id = res_tn.id INNER JOIN seminar_texty AS zad_text ON zad_on.text_id = zad_text.id INNER JOIN seminar_texty AS res_text ON res_on.text_id = res_text.id + -- Ročník tématu: + -- Podle rootu TvCN + INNER JOIN seminar_nodes_rocnik AS rn ON ttn.root_id = rn.treenode_ptr_id ORDER BY problem_ptr_id""" - same_fields = ['text_zadani', 'text_reseni'] + same_fields = ['text_zadani', 'text_reseni', 'rocnik_id'] renamed_fields = [ ('typ', 'tema_typ'), ] @@ -354,7 +361,6 @@ def check_tema(): for o,n in res: check_same(o,n, old_fields, new_fields) - #TODO: Tema.rocnik def check_konfera(): old_query = "SELECT * FROM seminar_problemy WHERE typ = 'konfera'" From 606f1f97cef26144dbdccac8103e8b780e612372 Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Wed, 2 Jun 2021 03:01:45 +0200 Subject: [PATCH 12/55] Fix case --- db_compare.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db_compare.py b/db_compare.py index 683e2037..bb29944d 100644 --- a/db_compare.py +++ b/db_compare.py @@ -327,7 +327,7 @@ def check_uloha(): def check_tema(): old_query = """SELECT text_zadani, text_reseni, typ, c.rocnik_id AS rocnik_id FROM seminar_problemy - INNER JOIN seminar_cisla as c ON c.id = cislo_zadani_id + INNER JOIN seminar_cisla AS c ON c.id = cislo_zadani_id WHERE typ IN ('tema', 'serial') ORDER BY id""" new_query = """SELECT tema_typ, zad_text.na_web AS text_zadani, res_text.na_web AS text_reseni, rn.rocnik_id AS rocnik_id From c679c5cfd1e2dad3feba14bdfca831f98abd2869 Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Wed, 2 Jun 2021 03:17:18 +0200 Subject: [PATCH 13/55] =?UTF-8?q?V=C3=BDsledek=20nem=C3=A1=20te=C4=8Dky,?= =?UTF-8?q?=20upraveny=20dotazy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db_compare.py | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/db_compare.py b/db_compare.py index bb29944d..e8c73008 100644 --- a/db_compare.py +++ b/db_compare.py @@ -64,7 +64,10 @@ def check_skola(): def check_resitel(): old_query = 'SELECT * FROM seminar_resitele ORDER BY id' - new_query = 'SELECT * FROM seminar_resitele JOIN seminar_osoby ON seminar_resitele.osoba_id = seminar_osoby.id ORDER BY seminar_resitele.id' + new_query = '''SELECT id, skola_id, rok_maturity, zasilat, poznamka, + o.jmeno AS jmeno, o.prijmeni AS prijmeni, o.user_id AS user_id, o.pohlavi_muz AS pohlavi_muz, o.email AS email, o.telefon AS telefon, o.datum_narozeni AS datum_narozeni, + o.datum_souhlasu_udaje AS datum_souhlasu_udaje, o.datum_souhlasu_zasilani AS datum_souhlasu_zasilani, o.datum_prihlaseni AS datum_prihlaseni, o.ulice AS ulice, o.mesto AS mesto, o.psc AS psc, o.stat AS stat + FROM seminar_resitele JOIN seminar_osoby AS o ON seminar_resitele.osoba_id = seminar_osoby.id ORDER BY seminar_resitele.id''' old_res, new_res = execute_simple(old_query,new_query) @@ -73,7 +76,7 @@ def check_resitel(): fields_osoba = [ 'jmeno', 'prijmeni', - 'user', + 'user_id', 'pohlavi_muz', 'email', 'telefon', @@ -93,20 +96,19 @@ def check_resitel(): 'zasilat', 'poznamka', ] - fields_old = fields_keep+fields_osoba - fields_new = fields_keep + ['seminar_osoby.'+f for f in fields_osoba] + fields = fields_keep+fields_osoba for o,n in res: - check_same(o,n,fields_old, fields_new) + check_same(o,n,fields) def check_reseni(): old_query = 'SELECT * FROM seminar_reseni ORDER BY id' - new_query = 'SELECT * FROM seminar_reseni JOIN seminar_hodnoceni AS hodnoceni ON hodnoceni_id = hodnoceni.id ORDER BY id' + new_query = 'SELECT id, forma, poznamka, cas_doruceni, hodnoceni.problem_id AS h_problem_id, hodnoceni.body AS h_body, hodnoceni.cislo_body_id AS h_cislo_body_id FROM seminar_reseni JOIN seminar_hodnoceni AS hodnoceni ON hodnoceni_id = hodnoceni.id ORDER BY id' same_fields = ['id', 'forma', 'poznamka'] renamed_fields = [('timestamp', 'cas_doruceni'), - ('problem_id', 'hodnoceni.problem_id'), - ('body', 'hodnoceni.body'), - ('cislo_body_id', 'hodnoceni.cislo_body_id'), + ('problem_id', 'h_problem_id'), + ('body', 'h_body'), + ('cislo_body_id', 'h_cislo_body_id'), ] old_fields = same_fields + [f[0] for f in renamed_fields] new_fields = same_fields + [f[1] for f in renamed_fields] @@ -133,14 +135,14 @@ def check_reseni(): def check_organizator(): old_query = 'SELECT * FROM seminar_organizatori ORDER BY id' - new_query = 'SELECT * FROM seminar_organizatori JOIN seminar_osoby AS osoba ON osoba_id = osoba.id JOIN auth_user AS user ON osoba.user_id = user.id ORDER BY id' + new_query = 'SELECT studuje, strucny_popis_organizatora, user.id AS uid, osoba.prezdivka AS o_prezdivka, osoba.foto AS o_foto, osoba.foto_male AS o_foto_male FROM seminar_organizatori JOIN seminar_osoby AS osoba ON osoba_id = osoba.id JOIN auth_user AS user ON osoba.user_id = user.id ORDER BY id' same_fields = ['studuje', 'strucny_popis_organizatora'] renamed_fields = [ - ('user_id', 'user.id'), - ('prezdivka', 'osoba.prezdivka'), - ('foto', 'osoba.foto'), - ('foto_male', 'osoba.foto_male'), + ('user_id', 'uid'), + ('prezdivka', 'o_prezdivka'), + ('foto', 'o_foto'), + ('foto_male', 'o_foto_male'), ] old_fields = same_fields + [f[0] for f in renamed_fields] new_fields = same_fields + [f[1] for f in renamed_fields] From 52f5259040312547d0d7054c29c9dab16fccfe18 Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Wed, 2 Jun 2021 03:28:37 +0200 Subject: [PATCH 14/55] =?UTF-8?q?Zam=C4=9B=C5=99en=C3=AD=20detail?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db_compare.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db_compare.py b/db_compare.py index e8c73008..d51345ca 100644 --- a/db_compare.py +++ b/db_compare.py @@ -287,7 +287,7 @@ def check_problem_common(): if oldr not in new_results: raise ValueError(f'Opravovatel pair {oldr} not found in new db.') - # FIXME: Zaměření? + # FIXME: Zaměření? Závislost je opačným směrem, přes content type a object id. Asi se to dobastlit dá, ale nevím, jestli to za to stojí. def check_uloha(): From e711c22aa3a3d3c24fcfe1646f2476b308148491 Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Tue, 8 Jun 2021 19:59:31 +0200 Subject: [PATCH 15/55] =?UTF-8?q?FIXME=20zam=C3=ADtnuto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db_compare.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db_compare.py b/db_compare.py index d51345ca..f5ec2a18 100644 --- a/db_compare.py +++ b/db_compare.py @@ -287,7 +287,7 @@ def check_problem_common(): if oldr not in new_results: raise ValueError(f'Opravovatel pair {oldr} not found in new db.') - # FIXME: Zaměření? Závislost je opačným směrem, přes content type a object id. Asi se to dobastlit dá, ale nevím, jestli to za to stojí. + # Zaměření se vyřeší okometricky (#1186) def check_uloha(): From 8b9357d3d60e679598043e1e8eefd43983633d1c Mon Sep 17 00:00:00 2001 From: Tomas 'Jethro' Pokorny Date: Tue, 8 Jun 2021 22:30:25 +0200 Subject: [PATCH 16/55] Bugfixes, broken check_organizator. --- db_compare.py | 58 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/db_compare.py b/db_compare.py index d51345ca..1a7b9578 100644 --- a/db_compare.py +++ b/db_compare.py @@ -38,7 +38,7 @@ def check_same(old_row, new_row, old_fields, new_fields=None): for old_field, new_field in fields: if old_row[old_field] == new_row[new_field]: continue - raise ValueError(f"Fields '{old_field}' and '{new_field}' differs for rows \n'{old_row}' and \n'{new_row}'") + raise ValueError(f"Fields '{old_field}'({old_row[old_field]}) and '{new_field}'({new_row[new_field]}) differs for rows \n'{old_row}' and \n'{new_row}'") return True def get_user_id_for_org_id(org_id): @@ -64,10 +64,10 @@ def check_skola(): def check_resitel(): old_query = 'SELECT * FROM seminar_resitele ORDER BY id' - new_query = '''SELECT id, skola_id, rok_maturity, zasilat, poznamka, + new_query = '''SELECT seminar_resitele.id, skola_id, rok_maturity, zasilat, seminar_resitele.poznamka, o.jmeno AS jmeno, o.prijmeni AS prijmeni, o.user_id AS user_id, o.pohlavi_muz AS pohlavi_muz, o.email AS email, o.telefon AS telefon, o.datum_narozeni AS datum_narozeni, - o.datum_souhlasu_udaje AS datum_souhlasu_udaje, o.datum_souhlasu_zasilani AS datum_souhlasu_zasilani, o.datum_prihlaseni AS datum_prihlaseni, o.ulice AS ulice, o.mesto AS mesto, o.psc AS psc, o.stat AS stat - FROM seminar_resitele JOIN seminar_osoby AS o ON seminar_resitele.osoba_id = seminar_osoby.id ORDER BY seminar_resitele.id''' + o.datum_souhlasu_udaje AS datum_souhlasu_udaje, o.datum_souhlasu_zasilani AS datum_souhlasu_zasilani, o.datum_registrace AS datum_prihlaseni, o.ulice AS ulice, o.mesto AS mesto, o.psc AS psc, o.stat AS stat + FROM seminar_resitele JOIN seminar_osoby AS o ON seminar_resitele.osoba_id = o.id ORDER BY seminar_resitele.id''' old_res, new_res = execute_simple(old_query,new_query) @@ -78,7 +78,7 @@ def check_resitel(): 'prijmeni', 'user_id', 'pohlavi_muz', - 'email', + #'email', #TODO: potřeba dořešit, protože merge řešitele a organizátora 'telefon', 'datum_narozeni', 'datum_souhlasu_udaje', @@ -102,7 +102,10 @@ def check_resitel(): def check_reseni(): old_query = 'SELECT * FROM seminar_reseni ORDER BY id' - new_query = 'SELECT id, forma, poznamka, cas_doruceni, hodnoceni.problem_id AS h_problem_id, hodnoceni.body AS h_body, hodnoceni.cislo_body_id AS h_cislo_body_id FROM seminar_reseni JOIN seminar_hodnoceni AS hodnoceni ON hodnoceni_id = hodnoceni.id ORDER BY id' + new_query = '''SELECT seminar_reseni.id, forma, poznamka, cas_doruceni, hodnoceni.problem_id AS h_problem_id, hodnoceni.body AS h_body, hodnoceni.cislo_body_id AS h_cislo_body_id + FROM seminar_reseni + JOIN seminar_hodnoceni AS hodnoceni ON seminar_reseni.id = hodnoceni.reseni_id + ORDER BY id''' same_fields = ['id', 'forma', 'poznamka'] renamed_fields = [('timestamp', 'cas_doruceni'), @@ -122,27 +125,32 @@ def check_reseni(): # Řešitelé jsou nově m2m, takže je musíme dohledat old_query = 'SELECT id, resitel_id FROM seminar_reseni ORDER BY id' - new_query = 'SELECT reseni_id, resitel_id FROM seminar_reseni_resitele ORDER BY reseni_id' + new_query = 'SELECT reseni_id, resitele_id FROM seminar_reseni_resitele ORDER BY reseni_id' - oldcur = oldconn.cursor() - old_results = oldcur.execute(old_query).fetchall() - newcur = newconn.cursor() - new_results = newcur.execute(new_query).fetchall() + #oldcur = oldconn.cursor() + oldcur.execute(old_query) + old_results = oldcur.fetchall() + #newcur = newconn.cursor() + newcur.execute(new_query) + new_results = newcur.fetchall() for oldr in old_results: if oldr not in new_results: raise ValueError(f'Reseni pair {oldr} not found in new db.') def check_organizator(): - old_query = 'SELECT * FROM seminar_organizatori ORDER BY id' - new_query = 'SELECT studuje, strucny_popis_organizatora, user.id AS uid, osoba.prezdivka AS o_prezdivka, osoba.foto AS o_foto, osoba.foto_male AS o_foto_male FROM seminar_organizatori JOIN seminar_osoby AS osoba ON osoba_id = osoba.id JOIN auth_user AS user ON osoba.user_id = user.id ORDER BY id' + old_query = 'SELECT * FROM seminar_organizator ORDER BY id' + new_query = '''SELECT seminar_organizator.id AS id, studuje, strucny_popis_organizatora, users.id AS uid, osoba.prezdivka AS o_prezdivka, osoba.foto AS o_foto, organizuje_od, organizuje_do + FROM seminar_organizator + JOIN seminar_osoby AS osoba ON osoba_id = osoba.id + JOIN auth_user AS users ON osoba.user_id = users.id + ORDER BY seminar_organizator.id''' same_fields = ['studuje', 'strucny_popis_organizatora'] renamed_fields = [ ('user_id', 'uid'), - ('prezdivka', 'o_prezdivka'), + #('prezdivka', 'o_prezdivka'), ('foto', 'o_foto'), - ('foto_male', 'o_foto_male'), ] old_fields = same_fields + [f[0] for f in renamed_fields] new_fields = same_fields + [f[1] for f in renamed_fields] @@ -152,10 +160,18 @@ def check_organizator(): for o,n in res: check_same(o,n,old_fields, new_fields) # organizuje od, do: - if o.organizuje_od_roku != n.organizuje_od.year: - raise ValueError(f'Not matching organizuje_od for org id={o.id}: old {o.organizuje_od_roku}, new {n.organizuje_od}') - if o.organizuje_do_roku != n.organizuje_do.year: - raise ValueError(f'Not matching organizuje_do for org id={o.id}: old {o.organizuje_do_roku}, new {n.organizuje_do}') + print(list(o.keys()),list(n.keys())) + if o['organizuje_od_roku'] != n['organizuje_od'].year: + raise ValueError(f'Not matching organizuje_od for org id={o["id"]}: old {o["organizuje_od_roku"]}, new {n["organizuje_od"]}') + if o['organizuje_do_roku'] != n['organizuje_do'].year: + raise ValueError(f'Not matching organizuje_do for org id={o["id"]}: old {o["organizuje_do_roku"]}, new {n["organizuje_do"]}') + if o['prezdivka'] == n['o_prezdivka']: + continue + if o['prezdivka'] is None and n['o_prezdivka'] == '': + continue + print(o,n) + raise ValueError(f'Not matching prezdivka for org id={o["id"]}: old {o["prezdivka"]}, new {n["o_prezdivka"]}') + def check_rocnik(): old_query = "SELECT * FROM seminar_rocniky ORDER BY id" @@ -278,9 +294,9 @@ def check_problem_common(): new_query = "SELECT problem_id, opravovatel_id FROM seminar_problemy_opravovatele" # Simple cursors - oldcur = oldconn.cursor() + #oldcur = oldconn.cursor() old_results = oldcur.execute(old_query).fetchall() - newcur = newconn.cursor() + #newcur = newconn.cursor() new_results = newcur.execute(new_query).fetchall() for oldr in old_results: From 2c2ec65a1b18a8f7567bc281e61c46f67f5aaef3 Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Tue, 8 Jun 2021 20:56:51 +0000 Subject: [PATCH 17/55] Zvraceny zvracene zmeny migr 0058 --- .../migrations/0058_problem_to_uloha_tema_clanek.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/seminar/migrations/0058_problem_to_uloha_tema_clanek.py b/seminar/migrations/0058_problem_to_uloha_tema_clanek.py index ebd2d6fb..ce84e542 100644 --- a/seminar/migrations/0058_problem_to_uloha_tema_clanek.py +++ b/seminar/migrations/0058_problem_to_uloha_tema_clanek.py @@ -49,7 +49,7 @@ def uloha_to_Uloha(apps,schema_editor): TextNode = apps.get_model('seminar', 'TextNode') ulohy = Problem.objects.filter(typ = 'uloha') - for uold in ulohy[1:]: + for uold in ulohy: unew = Uloha.objects.create( # Zakomentované fieldy by se už měly nacházet v příslušném problému nazev = uold.nazev, @@ -66,8 +66,6 @@ def uloha_to_Uloha(apps,schema_editor): unew.save() unew.opravovatele.add(*uold.opravovatele.all()) - return - # Nody: zadani_node = UlohaZadaniNode.objects.create(uloha = unew) poskladej_strom(apps, zadani_node, uold.text_zadani) @@ -164,7 +162,7 @@ class Migration(migrations.Migration): operations = [ # ashes to Ashes, dust to Dust.... migrations.RunPython(uloha_to_Uloha, migrations.RunPython.noop), - # migrations.RunPython(tema_to_Tema, migrations.RunPython.noop), - # migrations.RunPython(clanek_to_Clanek, migrations.RunPython.noop), - # migrations.RunPython(konfery_rucne, migrations.RunPython.noop), + migrations.RunPython(tema_to_Tema, migrations.RunPython.noop), + migrations.RunPython(clanek_to_Clanek, migrations.RunPython.noop), + migrations.RunPython(konfery_rucne, migrations.RunPython.noop), ] From 23caabba6b49c42a1c44979f1dda9bc92e4f88ec Mon Sep 17 00:00:00 2001 From: Tomas 'Jethro' Pokorny Date: Tue, 8 Jun 2021 22:57:17 +0200 Subject: [PATCH 18/55] Bugfixy mighraci --- db_compare.py | 10 ++++++---- ...na_prezdivka.py => 0085_nepovinna_prezdivka.py_old} | 4 +++- seminar/migrations/0086_auto_20200819_0959.py | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) rename seminar/migrations/{0085_nepovinna_prezdivka.py => 0085_nepovinna_prezdivka.py_old} (85%) diff --git a/db_compare.py b/db_compare.py index 413bd948..2d4e9c16 100644 --- a/db_compare.py +++ b/db_compare.py @@ -160,16 +160,18 @@ def check_organizator(): for o,n in res: check_same(o,n,old_fields, new_fields) # organizuje od, do: - print(list(o.keys()),list(n.keys())) - if o['organizuje_od_roku'] != n['organizuje_od'].year: + if o['organizuje_do_roku'] is None and n['organizuje_do'] is None: + pass + elif o['organizuje_od_roku'] != n['organizuje_od'].year: raise ValueError(f'Not matching organizuje_od for org id={o["id"]}: old {o["organizuje_od_roku"]}, new {n["organizuje_od"]}') - if o['organizuje_do_roku'] != n['organizuje_do'].year: + if o['organizuje_do_roku'] is None and n['organizuje_do'] is None: + pass + elif o['organizuje_do_roku'] != n['organizuje_do'].year: raise ValueError(f'Not matching organizuje_do for org id={o["id"]}: old {o["organizuje_do_roku"]}, new {n["organizuje_do"]}') if o['prezdivka'] == n['o_prezdivka']: continue if o['prezdivka'] is None and n['o_prezdivka'] == '': continue - print(o,n) raise ValueError(f'Not matching prezdivka for org id={o["id"]}: old {o["prezdivka"]}, new {n["o_prezdivka"]}') diff --git a/seminar/migrations/0085_nepovinna_prezdivka.py b/seminar/migrations/0085_nepovinna_prezdivka.py_old similarity index 85% rename from seminar/migrations/0085_nepovinna_prezdivka.py rename to seminar/migrations/0085_nepovinna_prezdivka.py_old index b3bd19a4..4a8f02e0 100644 --- a/seminar/migrations/0085_nepovinna_prezdivka.py +++ b/seminar/migrations/0085_nepovinna_prezdivka.py_old @@ -1,5 +1,7 @@ # Generated by Django 2.2.13 on 2020-06-24 22:57 +# V současné době nepoužíván + from django.db import migrations, models def smaz_prezdivku(apps, schema_editor): @@ -26,7 +28,7 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='osoba', name='prezdivka', - field=models.CharField(blank=True, max_length=256, null=True, verbose_name='přezdívka'), + field=models.CharField(blank=True, max_length=256, verbose_name='přezdívka'), ), migrations.RunPython(smaz_prezdivku, pridej_prezdivku), ] diff --git a/seminar/migrations/0086_auto_20200819_0959.py b/seminar/migrations/0086_auto_20200819_0959.py index a5847e71..7b6b85a3 100644 --- a/seminar/migrations/0086_auto_20200819_0959.py +++ b/seminar/migrations/0086_auto_20200819_0959.py @@ -6,7 +6,7 @@ from django.db import migrations class Migration(migrations.Migration): dependencies = [ - ('seminar', '0085_nepovinna_prezdivka'), + ('seminar', '0084_clanek_cislo'), ] operations = [ From 9d7276578ad869db768981b7890c85447857fe80 Mon Sep 17 00:00:00 2001 From: Tomas 'Jethro' Pokorny Date: Tue, 8 Jun 2021 23:36:13 +0200 Subject: [PATCH 19/55] Bugfixy v migracich a kontrolach. --- db_compare.py | 24 +++++++++---------- seminar/migrations/0049_auto_20190430_2354.py | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/db_compare.py b/db_compare.py index 2d4e9c16..4cfe7659 100644 --- a/db_compare.py +++ b/db_compare.py @@ -310,24 +310,24 @@ def check_problem_common(): def check_uloha(): old_query = "SELECT * FROM seminar_problemy WHERE typ = 'uloha' ORDER BY id" - new_query = """SELECT cislo_zadani, cislo_reseni, problem_ptr_id, max_body, uzt.na_web AS text_zadani, uvt.na_web AS text_reseni + new_query = """SELECT cislo_zadani_id, cislo_reseni_id, problem_ptr_id, max_body, uzt.na_web AS text_zadani, uvt.na_web AS text_reseni FROM seminar_ulohy -- Problém: JOIN seminar_problemy AS problem ON problem_ptr_id = problem.id -- Text zadání: - INNER JOIN seminar_nodes_uloha_zadani AS uzn ON id = uzn.uloha_id + INNER JOIN seminar_nodes_uloha_zadani AS uzn ON problem.id = uzn.uloha_id INNER JOIN seminar_nodes_treenode AS uztn ON uztn.id = uzn.treenode_ptr_id INNER JOIN seminar_nodes_obsah AS uzo ON uzo.treenode_ptr_id = uztn.first_child_id INNER JOIN seminar_texty AS uzt ON uzo.text_id = uzt.id -- Text vzoráku: - INNER JOIN seminar_nodes_uloha_zadani AS uvn ON id = uvn.uloha_id + INNER JOIN seminar_nodes_uloha_zadani AS uvn ON problem.id = uvn.uloha_id INNER JOIN seminar_nodes_treenode AS uvtn ON uvtn.id = uvn.treenode_ptr_id INNER JOIN seminar_nodes_obsah AS uvo ON uvo.treenode_ptr_id = uvtn.first_child_id INNER JOIN seminar_texty AS uvt ON uvo.text_id = uvt.id ORDER BY problem_ptr_id""" - same_fields = ['cislo_zadani', 'cislo_reseni', 'text_zadani', 'text_reseni'] + same_fields = ['cislo_zadani_id', 'cislo_reseni_id', 'text_zadani', 'text_reseni'] renamed_fields = [ ('id', 'problem_ptr_id'), ('body', 'max_body'), @@ -349,7 +349,7 @@ def check_tema(): FROM seminar_problemy INNER JOIN seminar_cisla AS c ON c.id = cislo_zadani_id WHERE typ IN ('tema', 'serial') - ORDER BY id""" + ORDER BY seminar_problemy.id""" new_query = """SELECT tema_typ, zad_text.na_web AS text_zadani, res_text.na_web AS text_reseni, rn.rocnik_id AS rocnik_id FROM seminar_temata -- Problém: @@ -408,10 +408,10 @@ def check_res_clanek(): JOIN seminar_problemy AS problem ON problem_ptr_id = problem.id INNER JOIN seminar_hodnoceni AS hodn ON problem.id = hodn.problem_id INNER JOIN seminar_reseni AS rese ON rese.id = hodn.reseni_id - INNER JOIN seminar_nodes_reseni AS resnode ON resnode.reseni_id = rese.id + INNER JOIN seminar_nodes_otistene_reseni AS resnode ON resnode.reseni_id = rese.id INNER JOIN seminar_nodes_treenode AS tn ON resnode.treenode_ptr_id = tn.id - INNER JOIN seminar_nodes_obsah AS on ON on.treenode_ptr_id = tn.first_child_id - INNER JOIN seminar_texty AS text ON text.id = on.text_id + INNER JOIN seminar_nodes_obsah AS son ON son.treenode_ptr_id = tn.first_child_id + INNER JOIN seminar_texty AS text ON text.id = son.text_id ORDER BY problem_ptr_id""" same_fields = ['text_zadani'] @@ -451,10 +451,10 @@ check_nastaveni() check_novinky() check_pohadka() -check_problem_common() -check_uloha() -check_tema() +#check_problem_common() - RUZNE POCTY RADKU +#check_uloha() - RUNE POCTY RADKU +#check_tema() - RUZNE POCTY RADKU check_konfera() check_org_clanek() -check_res_clanek() +#check_res_clanek() - RUZNE POCTY RADKU check_untyped_problem() diff --git a/seminar/migrations/0049_auto_20190430_2354.py b/seminar/migrations/0049_auto_20190430_2354.py index 985b3531..8abe0460 100644 --- a/seminar/migrations/0049_auto_20190430_2354.py +++ b/seminar/migrations/0049_auto_20190430_2354.py @@ -63,7 +63,7 @@ class Migration(migrations.Migration): ('id', models.AutoField(primary_key=True, serialize=False)), ('jmeno', models.CharField(max_length=256, verbose_name='jméno')), ('prijmeni', models.CharField(max_length=256, verbose_name='příjmení')), - ('prezdivka', models.CharField(max_length=256, verbose_name='přezdívka')), + ('prezdivka', models.CharField(max_length=256, verbose_name='přezdívka', blank=True, null=False)), ('pohlavi_muz', models.BooleanField(default=False, verbose_name='pohlaví (muž)')), ('email', models.EmailField(blank=True, default='', max_length=256, verbose_name='e-mail')), ('telefon', models.CharField(blank=True, default='', max_length=256, verbose_name='telefon')), From 34937391ff12d87d5d556136eaeb36154c1c33c4 Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Tue, 8 Jun 2021 23:39:43 +0200 Subject: [PATCH 20/55] =?UTF-8?q?Poh=C3=A1dka=20otestov=C3=A1na?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db_compare.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/db_compare.py b/db_compare.py index 4cfe7659..a6013723 100644 --- a/db_compare.py +++ b/db_compare.py @@ -254,12 +254,19 @@ def check_novinky(): def check_pohadka(): old_query = "SELECT * FROM seminar_pohadky ORDER BY id" - new_query = """SELECT sp.id AS id, sp.autor_id AS autor_id, sp.vytvoreno AS vytvoreno, snp.treenode_ptr_id AS treenode_ptr_id, st.na_web AS text + new_query = """SELECT sp.id AS id, sp.autor_id AS autor_id, sp.vytvoreno AS vytvoreno, snp.treenode_ptr_id AS treenode_ptr_id, st.na_web AS text, + zn_pred.uloha_id AS uloha_pred, zn_po.uloha_id AS uloha_po FROM seminar_pohadky AS sp + -- Text pohádky INNER JOIN seminar_nodes_pohadka AS snp ON sp.id = snp.pohadka_id INNER JOIN seminar_nodes_treenode AS snt ON snt.id = snp.treenode_ptr_id INNER JOIN seminar_nodes_obsah AS sno ON sno.treenode_ptr_id = snt.first_child_id INNER JOIN seminar_texty AS st ON sno.text_id = st.id + -- Predchozí úloha + LEFT OUTER JOIN seminar_nodes_treenode AS ztn_pred ON ztn_pred.succ_id = snt.id + INNER JOIN seminar_nodes_uloha AS zn_pred ON zn_pred.treenode_ptr_id = ztn_pred.id + -- Následující úloha + LEFT OUTER JOIN seminar_nodes_uloha_zadani AS zn_po ON zn_po.treenode_ptr_id = snt.succ_id ORDER BY sp.id""" @@ -271,6 +278,10 @@ def check_pohadka(): if o['autor_id'] is not None: if get_user_id_for_org_id(n['autor_id']) != o['autor_id']: raise ValueError("Nesedi autori u pohadky") + # Správné úlohy + spravny_klic = 'uloha_pred' if o['pred'] else 'uloha_po' + if o['uloha_id'] != n[spravny_klic]: + raise ValueError(f"Pohádka přidružená ke špatné úloze! old: {o['uloha_id']}, new: {n[spravny_klic]}, pozice: {spravny_klic}") # Problémy jsou rozdělené podle typů: From 49b3174a6241e7bb3d904466311c6e0395ae82a5 Mon Sep 17 00:00:00 2001 From: Tomas 'Jethro' Pokorny Date: Tue, 8 Jun 2021 23:51:12 +0200 Subject: [PATCH 21/55] Bugfixy. --- db_compare.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/db_compare.py b/db_compare.py index a6013723..3eab02a7 100644 --- a/db_compare.py +++ b/db_compare.py @@ -264,7 +264,7 @@ def check_pohadka(): INNER JOIN seminar_texty AS st ON sno.text_id = st.id -- Predchozí úloha LEFT OUTER JOIN seminar_nodes_treenode AS ztn_pred ON ztn_pred.succ_id = snt.id - INNER JOIN seminar_nodes_uloha AS zn_pred ON zn_pred.treenode_ptr_id = ztn_pred.id + LEFT OUTER JOIN seminar_nodes_uloha_zadani AS zn_pred ON zn_pred.treenode_ptr_id = ztn_pred.id -- Následující úloha LEFT OUTER JOIN seminar_nodes_uloha_zadani AS zn_po ON zn_po.treenode_ptr_id = snt.succ_id @@ -462,10 +462,10 @@ check_nastaveni() check_novinky() check_pohadka() -#check_problem_common() - RUZNE POCTY RADKU -#check_uloha() - RUNE POCTY RADKU -#check_tema() - RUZNE POCTY RADKU +check_problem_common() +check_uloha() +check_tema() check_konfera() check_org_clanek() -#check_res_clanek() - RUZNE POCTY RADKU +check_res_clanek() check_untyped_problem() From fa18f1b5e78ec4bca1431f2f3aea7aeb501b7abb Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Tue, 8 Jun 2021 22:25:39 +0000 Subject: [PATCH 22/55] Chybejici problem_ptr u migrace uloh --- seminar/migrations/0058_problem_to_uloha_tema_clanek.py | 1 + 1 file changed, 1 insertion(+) diff --git a/seminar/migrations/0058_problem_to_uloha_tema_clanek.py b/seminar/migrations/0058_problem_to_uloha_tema_clanek.py index ce84e542..dbab46ad 100644 --- a/seminar/migrations/0058_problem_to_uloha_tema_clanek.py +++ b/seminar/migrations/0058_problem_to_uloha_tema_clanek.py @@ -52,6 +52,7 @@ def uloha_to_Uloha(apps,schema_editor): for uold in ulohy: unew = Uloha.objects.create( # Zakomentované fieldy by se už měly nacházet v příslušném problému + problem_ptr = uold, nazev = uold.nazev, stav = uold.stav, zamereni = uold.zamereni, From d051125f8d8ee142b73ae8d82f24446d6683650e Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Tue, 8 Jun 2021 22:26:05 +0000 Subject: [PATCH 23/55] Smazan kod pro org-clanky -- stejne neexistuji --- seminar/migrations/0058_problem_to_uloha_tema_clanek.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/seminar/migrations/0058_problem_to_uloha_tema_clanek.py b/seminar/migrations/0058_problem_to_uloha_tema_clanek.py index dbab46ad..5694960c 100644 --- a/seminar/migrations/0058_problem_to_uloha_tema_clanek.py +++ b/seminar/migrations/0058_problem_to_uloha_tema_clanek.py @@ -89,7 +89,8 @@ def clanek_to_Clanek(apps,schema_editor): Text = apps.get_model('seminar', 'Text') TextNode = apps.get_model('seminar', 'TextNode') - clanky = Problem.objects.filter(Q(typ='org-clanek') | Q(typ='res-clanek')) + # XXX: Org-clanky neexistuji, tak je migrace ani nepodporuje. + clanky = Problem.objects.filter(typ='res-clanek') for cl in clanky: # Vybereme vhodné číslo pro článek z čísla zadání a čísla řešení: if cl.cislo_zadani_old is None: @@ -102,17 +103,13 @@ def clanek_to_Clanek(apps,schema_editor): raise ValueError("Různá čísla zadání a řešení u článku! (Článek: {})".format(cl.nazev)) clnew = Clanek.objects.create( - problem_ptr_id = cl.id, + problem_ptr = cl, # Problém by nemělo být potřeba upravovat cislo = cislo, # Body ignorujeme, protože už jsou v hodnocení ) clnew.save() - # Aktuálně nemáme v modelu informaci o tom, jestli je to org-článek - # nebo řešitelský článek. Aby se neztratila informace, poznamenám to do - # poznámky. - cl.poznamka += "\nTyp:\t{}".format(cl.typ) cl.save() # Vyrobíme nody: From a7efe1c691c5c862fa6e749b9a77e53857f613ce Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Tue, 8 Jun 2021 22:26:59 +0000 Subject: [PATCH 24/55] Mrtvy kod --- seminar/migrations/0058_problem_to_uloha_tema_clanek.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/seminar/migrations/0058_problem_to_uloha_tema_clanek.py b/seminar/migrations/0058_problem_to_uloha_tema_clanek.py index 5694960c..3c947b24 100644 --- a/seminar/migrations/0058_problem_to_uloha_tema_clanek.py +++ b/seminar/migrations/0058_problem_to_uloha_tema_clanek.py @@ -32,13 +32,6 @@ def poskladej_strom(apps, rodic, *texty): tn.succ = textnode tn.save() tn = tn.succ -def problem_to_polymorphic_Problem(apps,schema_editor): - Problem = apps.get_model('seminar', 'Problem') - ContentType = apps.get_model('contenttypes', 'ContentType') - - new_ct = ContentType.objects.get_for_model(Problem) - Problem.objects.filter(polymorphic_ctype__isnull=True).update(polymorphic_ctype=new_ct) - def uloha_to_Uloha(apps,schema_editor): Problem = apps.get_model('seminar', 'Problem') From d9437041d10264e702963a1f8ec3b535069dfdcb Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Wed, 9 Jun 2021 00:20:50 +0000 Subject: [PATCH 25/55] db_compare mode +x --- db_compare.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 db_compare.py diff --git a/db_compare.py b/db_compare.py old mode 100644 new mode 100755 index 3eab02a7..5fe11eba --- a/db_compare.py +++ b/db_compare.py @@ -1,4 +1,4 @@ -#!/usr/bin/python3 +#!/usr/bin/env python3 import psycopg2 import psycopg2.extras From 36c3cc6814248944415f87a8b6cf015c110d438a Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Wed, 9 Jun 2021 00:21:26 +0000 Subject: [PATCH 26/55] Par fixu --- db_compare.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/db_compare.py b/db_compare.py index 5fe11eba..d4e1a777 100755 --- a/db_compare.py +++ b/db_compare.py @@ -288,7 +288,7 @@ def check_pohadka(): def check_problem_common(): query = "SELECT * FROM seminar_problemy ORDER BY id" - same_fields = ['id', 'nazev', 'stav', 'autor', 'kod'] + same_fields = ['id', 'nazev', 'stav', 'autor_id', 'kod'] renamed_fields = [ ('text_org', 'poznamka'), ('timestamp', 'vytvoreno'), @@ -395,7 +395,7 @@ def check_tema(): def check_konfera(): old_query = "SELECT * FROM seminar_problemy WHERE typ = 'konfera'" - new_query = "SELECT * FROM seminar_konfera JOIN seminar_problemy AS problem ON problem_ptr_id = problem.id" + new_query = "SELECT * FROM seminar_konfera AS k JOIN seminar_problemy AS problem ON k.problem_ptr_id = problem.id" oldcur.execute(old_query) newcur.execute(new_query) From b381f46b23c7a2b053ff7bb9b752de47c32acf17 Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Tue, 22 Jun 2021 20:41:01 +0000 Subject: [PATCH 27/55] Spojovani reseni pro Clanky, aby mely jen jedno... --- db_compare.py | 52 ++++++++++++------- .../0058_problem_to_uloha_tema_clanek.py | 40 ++++++++++++++ 2 files changed, 73 insertions(+), 19 deletions(-) diff --git a/db_compare.py b/db_compare.py index d4e1a777..819805e1 100755 --- a/db_compare.py +++ b/db_compare.py @@ -101,42 +101,56 @@ def check_resitel(): check_same(o,n,fields) def check_reseni(): - old_query = 'SELECT * FROM seminar_reseni ORDER BY id' - new_query = '''SELECT seminar_reseni.id, forma, poznamka, cas_doruceni, hodnoceni.problem_id AS h_problem_id, hodnoceni.body AS h_body, hodnoceni.cislo_body_id AS h_cislo_body_id + # Migrace 0058 zamerne meni (zmensuje) pocet reseni, aby kazdy clanek mel + # jen jedno reseni (s vice resiteli, coz postaru neslo) + # Kvuli tomu je potreba kontrolovat dve veci: + # 1) Ze kazdy resitel dostal za kazdy problem spravne bodu + # 2) Ze detaily reseni zustaly zachovany + + # Cast 1) + old_query = 'SELECT * FROM seminar_reseni ORDER BY problem_id, resitel_id, body, timestamp' + new_query = '''SELECT seminar_reseni.id, forma, seminar_reseni.poznamka, cas_doruceni, hodnoceni.problem_id AS problem_id, hodnoceni.body AS body, hodnoceni.cislo_body_id AS cislo_body_id, res.id AS resitel_id FROM seminar_reseni JOIN seminar_hodnoceni AS hodnoceni ON seminar_reseni.id = hodnoceni.reseni_id - ORDER BY id''' + JOIN seminar_reseni_resitele AS rr ON seminar_reseni.id = rr.reseni_id + JOIN seminar_resitele AS res ON res.id = rr.resitele_id + ORDER BY problem_id, resitel_id, body, cas_doruceni''' - same_fields = ['id', 'forma', 'poznamka'] - renamed_fields = [('timestamp', 'cas_doruceni'), - ('problem_id', 'h_problem_id'), - ('body', 'h_body'), - ('cislo_body_id', 'h_cislo_body_id'), + # Po spojeni nekterych problemu se lisi casy doruceni a poznamky, proto je nebudeme kontrolovat (jde v podstate o triviality, tak je to snad jedno) + same_fields = ['forma', 'problem_id', 'body', 'cislo_body_id', 'resitel_id'] + renamed_fields = [ + #('timestamp', 'cas_doruceni'), ] old_fields = same_fields + [f[0] for f in renamed_fields] new_fields = same_fields + [f[1] for f in renamed_fields] - old_res, new_res = execute_simple(old_query,new_query) + old_res, new_res = execute_simple(old_query, new_query) res = zip(old_res,new_res) for o,n in res: check_same(o,n,old_fields, new_fields) - # Řešitelé jsou nově m2m, takže je musíme dohledat - old_query = 'SELECT id, resitel_id FROM seminar_reseni ORDER BY id' - new_query = 'SELECT reseni_id, resitele_id FROM seminar_reseni_resitele ORDER BY reseni_id' + # Cast 2) + # Query se lisi tim, ze uz nejoinujeme resitele. + old_query = 'SELECT * FROM seminar_reseni ORDER BY id' + new_query = '''SELECT seminar_reseni.id, forma, poznamka, cas_doruceni AS timestamp, h.problem_id AS problem_id, h.body AS body, h.cislo_body_id AS cislo_body_id + FROM seminar_reseni + JOIN seminar_hodnoceni AS h ON h.reseni_id = seminar_reseni.id + ORDER BY id''' - #oldcur = oldconn.cursor() + # execute_simple kontroluje stejnost poctu radku, to nechceme. oldcur.execute(old_query) - old_results = oldcur.fetchall() - #newcur = newconn.cursor() newcur.execute(new_query) - new_results = newcur.fetchall() + old_res, new_res = oldcur.fetchall(), newcur.fetchall() + # Zkontrolujeme, ze pro kazde nove reseni ma stare reseni spravna data. + new_ids = [n['id'] for n in new_res] + spravna_old = list(filter(lambda o: o['id'] in new_ids, old_res)) + res = zip(spravna_old,new_res) + for o,n in res: + check_same(o,n,['id', 'forma', 'poznamka', 'timestamp', 'problem_id', 'body', 'cislo_body_id']) + - for oldr in old_results: - if oldr not in new_results: - raise ValueError(f'Reseni pair {oldr} not found in new db.') def check_organizator(): old_query = 'SELECT * FROM seminar_organizator ORDER BY id' diff --git a/seminar/migrations/0058_problem_to_uloha_tema_clanek.py b/seminar/migrations/0058_problem_to_uloha_tema_clanek.py index 3c947b24..4b09aea9 100644 --- a/seminar/migrations/0058_problem_to_uloha_tema_clanek.py +++ b/seminar/migrations/0058_problem_to_uloha_tema_clanek.py @@ -110,6 +110,45 @@ def clanek_to_Clanek(apps,schema_editor): poskladej_strom(apps, clnode, cl.text_zadani, cl.text_reseni) clnode.save() +def fix_Clanek_Reseni(apps, schema_editor): + Problem = apps.get_model('seminar', 'Problem') + Clanek = apps.get_model('seminar', 'Clanek') + Reseni = apps.get_model('seminar', 'Reseni') + Hodnoceni = apps.get_model('seminar', 'Hodnoceni') + Resitel = apps.get_model('seminar', 'Resitel') + + # Je potreba zajistit, ze clanky budou mit jen jedno reseni -- z pohledu + # modelu nic jineho nedava smysl. Ve stavajicim modelu ale naopak nelze + # reprezentovat vice resitelu jednoho clanku (coz je ale bezne -- clanky z + # konfer) Musime tedy opravit, aby misto nekolika reseni kazdeho resitele + # samostatne zustalo jen jedno reseni, spravne obodovane a s vice resiteli + # jako autory + + for cl in Clanek.objects.all(): + rr = cl.reseni_set.all() + if len(rr) == 1: continue + # Vice nez jedno reseni, jdeme je sjednotit. + resitele = [] + vzor_hodnoceni = rr[0].hodnoceni_set.first() + ostatni_hodnoceni = [] + for r in rr: + # Overime, ze nemame kolizi v datech: + h = r.hodnoceni_set.first() + if h.cislo_body != vzor_hodnoceni.cislo_body or h.body != vzor_hodnoceni.body: + raise ValueError(f'Clanek {cl.id} ma vice nekonzistentnich reseni') + if h.id != vzor_hodnoceni.id: + ostatni_hodnoceni.append(h) + resitele.extend(r.resitele.all()) + print(f'*** cl={cl.id}, res={resitele}') + rr[0].resitele.set(resitele) + rr[0].save() + vzor_hodnoceni.save() + print(f'vzor = {vzor_hodnoceni}, ostatni = {ostatni_hodnoceni}') + # Ted mame spravne databazi, jeste potrebujeme z databaze smazat po novu nepouzita hodnoceni + for h in ostatni_hodnoceni: + h.reseni.delete() + h.delete() + def tema_to_Tema(apps, schema_editor): Problem = apps.get_model('seminar', 'Problem') Tema = apps.get_model('seminar', 'Tema') @@ -155,5 +194,6 @@ class Migration(migrations.Migration): migrations.RunPython(uloha_to_Uloha, migrations.RunPython.noop), migrations.RunPython(tema_to_Tema, migrations.RunPython.noop), migrations.RunPython(clanek_to_Clanek, migrations.RunPython.noop), + migrations.RunPython(fix_Clanek_Reseni, migrations.RunPython.noop), migrations.RunPython(konfery_rucne, migrations.RunPython.noop), ] From 42ccaa47b00acca94ac5263d649f609193953d79 Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Tue, 22 Jun 2021 20:41:30 +0000 Subject: [PATCH 28/55] Slozka na detaily nasazeni noveho webu + skript na sanitizaci db --- deploy_v2/README | 3 +++ deploy_v2/pre_migration.py | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 deploy_v2/README create mode 100755 deploy_v2/pre_migration.py diff --git a/deploy_v2/README b/deploy_v2/README new file mode 100644 index 00000000..dec6d746 --- /dev/null +++ b/deploy_v2/README @@ -0,0 +1,3 @@ +Tahle slozka obsahuje vsechny detaily a popisy, jak nasadit "druhou verzi" M&M webu. + +TODO: chybi tu popis na zprovozneni flatpages, na loaddata &c. diff --git a/deploy_v2/pre_migration.py b/deploy_v2/pre_migration.py new file mode 100755 index 00000000..45af8dc8 --- /dev/null +++ b/deploy_v2/pre_migration.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 + +import os +import sys + +import django + +#### Inicializace Djanga +sys.path.append(os.path.dirname(os.path.realpath(__file__))+'/..') +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mamweb.settings') +django.setup() + +## Pozor, nejde pouzit ORM, protoze kod je na jine verzi nez databaze a nejde namigrovat. +from django.db import connection + + +def smaz_zle_clanky(): + # Tyhle clanky vubec nejsou clanky, bude potreba je udelat cele jinak a spravne. + #m.Problem.objects.filter(id__in=[1981, 1970, 2222]).delete() + with connection.cursor() as cursor: + # Nejdriv musime smazat reseni: + cursor.execute('DELETE FROM seminar_reseni WHERE problem_id IN (1981, 1970, 2222);') + # Nakonec i ty clanky samotne + cursor.execute('DELETE FROM seminar_problemy WHERE id IN (1981, 1970, 2222);') + + +smaz_zle_clanky() From 0012e4733449c908f339d68f8ba58c08dc56c64a Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Tue, 22 Jun 2021 20:53:23 +0000 Subject: [PATCH 29/55] Spravna timezone pri kontrole dat organizace --- db_compare.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/db_compare.py b/db_compare.py index 819805e1..b76a7f5e 100755 --- a/db_compare.py +++ b/db_compare.py @@ -174,13 +174,16 @@ def check_organizator(): for o,n in res: check_same(o,n,old_fields, new_fields) # organizuje od, do: + # Migrace prirazuje aktualni casovou zonu, takze chceme tady rucne vynutit CET. + from datetime import timedelta, timezone + cet = timezone(timedelta(hours=1)) if o['organizuje_do_roku'] is None and n['organizuje_do'] is None: pass - elif o['organizuje_od_roku'] != n['organizuje_od'].year: + elif o['organizuje_od_roku'] != n['organizuje_od'].astimezone(cet).year: raise ValueError(f'Not matching organizuje_od for org id={o["id"]}: old {o["organizuje_od_roku"]}, new {n["organizuje_od"]}') if o['organizuje_do_roku'] is None and n['organizuje_do'] is None: pass - elif o['organizuje_do_roku'] != n['organizuje_do'].year: + elif o['organizuje_do_roku'] != n['organizuje_do'].astimezone(cet).year: raise ValueError(f'Not matching organizuje_do for org id={o["id"]}: old {o["organizuje_do_roku"]}, new {n["organizuje_do"]}') if o['prezdivka'] == n['o_prezdivka']: continue From c5b60c08f45b6d3efdb33350cd2dd7c47c9910df Mon Sep 17 00:00:00 2001 From: Tomas 'Jethro' Pokorny Date: Tue, 22 Jun 2021 23:11:00 +0200 Subject: [PATCH 30/55] Oprava ztracenych nazvu problemu, pada migrace 60. --- db_compare.py | 10 ++++++++-- .../migrations/0058_problem_to_uloha_tema_clanek.py | 10 +++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/db_compare.py b/db_compare.py index d4e1a777..0acd6808 100755 --- a/db_compare.py +++ b/db_compare.py @@ -286,7 +286,13 @@ def check_pohadka(): # Problémy jsou rozdělené podle typů: def check_problem_common(): - query = "SELECT * FROM seminar_problemy ORDER BY id" + old_query = "SELECT id, nazev, stav, kod, autor_id, text_org, timestamp, typ FROM seminar_problemy ORDER BY id" + new_query = """SELECT sp.id AS id, sp.nazev AS nazev, sp.stav AS stav, sp.kod AS kod, au.id AS autor_id, sp.poznamka AS poznamka, sp.vytvoreno AS vytvoreno + FROM seminar_problemy AS sp + LEFT OUTER JOIN seminar_organizator AS so ON sp.autor_id = so.id + LEFT OUTER JOIN seminar_osoby AS sos ON so.osoba_id = sos.id + LEFT OUTER JOIN auth_user AS au ON sos.user_id = au.id + ORDER BY sp.id""" same_fields = ['id', 'nazev', 'stav', 'autor_id', 'kod'] renamed_fields = [ @@ -296,7 +302,7 @@ def check_problem_common(): old_fields = same_fields + [f[0] for f in renamed_fields] new_fields = same_fields + [f[1] for f in renamed_fields] - old_res, new_res = execute_simple(query) + old_res, new_res = execute_simple(old_query,new_query) res = zip(old_res,new_res) for o,n in res: diff --git a/seminar/migrations/0058_problem_to_uloha_tema_clanek.py b/seminar/migrations/0058_problem_to_uloha_tema_clanek.py index 3c947b24..30a92e27 100644 --- a/seminar/migrations/0058_problem_to_uloha_tema_clanek.py +++ b/seminar/migrations/0058_problem_to_uloha_tema_clanek.py @@ -57,7 +57,7 @@ def uloha_to_Uloha(apps,schema_editor): max_body = uold.body, vytvoreno = uold.vytvoreno, ) - unew.save() + uold.save() # DULEZITE!!! Jinak Uloha.objects.create() přepíše všechny atributy Problému unew.opravovatele.add(*uold.opravovatele.all()) # Nody: @@ -101,9 +101,7 @@ def clanek_to_Clanek(apps,schema_editor): cislo = cislo, # Body ignorujeme, protože už jsou v hodnocení ) - clnew.save() - - cl.save() + cl.save() # DULEZITE!!! Jinak Clanek.objects.create() přepíše všechny atributy Problému # Vyrobíme nody: clnode = ClanekNode(clanek = clnew) @@ -118,6 +116,8 @@ def tema_to_Tema(apps, schema_editor): TextNode = apps.get_model('seminar', 'TextNode') temata = Problem.objects.filter(Q(typ = 'tema') | Q(typ='serial')) + #temata = Problem.objects.filter(id=635) + #temata = Problem.objects.filter(cislo_zadani_old__id=87) for t in temata: # Vymyslíme správně ročník: if t.cislo_zadani_old is None and t.cislo_reseni_old is None: @@ -136,7 +136,7 @@ def tema_to_Tema(apps, schema_editor): tema_typ = t.typ, rocnik = rocnik, ) - tnew.save() + t.save() # DULEZITE!!! Jinak Tema.objects.create() přepíše všechny atributy Problému # Nody: tnode = TemaVCisleNode(tema = tnew) From d66b8c3be216271f3c21f9e07a0cfd1ae6cae2c4 Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Tue, 22 Jun 2021 22:21:42 +0000 Subject: [PATCH 31/55] Spravne vyrobeni TreeNodu pro clanek --- .../0058_problem_to_uloha_tema_clanek.py | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/seminar/migrations/0058_problem_to_uloha_tema_clanek.py b/seminar/migrations/0058_problem_to_uloha_tema_clanek.py index 4b09aea9..e228f240 100644 --- a/seminar/migrations/0058_problem_to_uloha_tema_clanek.py +++ b/seminar/migrations/0058_problem_to_uloha_tema_clanek.py @@ -78,7 +78,7 @@ def konfery_rucne(apps, schema_editor): def clanek_to_Clanek(apps,schema_editor): Problem = apps.get_model('seminar', 'Problem') Clanek = apps.get_model('seminar', 'Clanek') - ClanekNode = apps.get_model('seminar', 'ClanekNode') + ReseniNode = apps.get_model('seminar', 'ReseniNode') Text = apps.get_model('seminar', 'Text') TextNode = apps.get_model('seminar', 'TextNode') @@ -105,10 +105,23 @@ def clanek_to_Clanek(apps,schema_editor): cl.save() + +def Clanek_Treenody(apps, schema_editor): + Problem = apps.get_model('seminar', 'Problem') + Clanek = apps.get_model('seminar', 'Clanek') + ReseniNode = apps.get_model('seminar', 'ReseniNode') + Text = apps.get_model('seminar', 'Text') + TextNode = apps.get_model('seminar', 'TextNode') + for cl in Clanek.objects.all(): # Vyrobíme nody: - clnode = ClanekNode(clanek = clnew) - poskladej_strom(apps, clnode, cl.text_zadani, cl.text_reseni) - clnode.save() + # Clanek nema vlastni node, ma (prave jedno) Reseni a to ma ReseniNode + reseni = cl.reseni_set.all() + if len(reseni) != 1: + raise ValueError(f'Clanek {cl.id} ma vic reseni {len(reseni)} ({reseni})') + reseni = reseni[0] + resnode = ReseniNode(reseni=reseni) + poskladej_strom(apps, resnode, cl.text_zadani, cl.text_reseni) + resnode.save() def fix_Clanek_Reseni(apps, schema_editor): Problem = apps.get_model('seminar', 'Problem') @@ -139,11 +152,9 @@ def fix_Clanek_Reseni(apps, schema_editor): if h.id != vzor_hodnoceni.id: ostatni_hodnoceni.append(h) resitele.extend(r.resitele.all()) - print(f'*** cl={cl.id}, res={resitele}') rr[0].resitele.set(resitele) rr[0].save() vzor_hodnoceni.save() - print(f'vzor = {vzor_hodnoceni}, ostatni = {ostatni_hodnoceni}') # Ted mame spravne databazi, jeste potrebujeme z databaze smazat po novu nepouzita hodnoceni for h in ostatni_hodnoceni: h.reseni.delete() @@ -195,5 +206,6 @@ class Migration(migrations.Migration): migrations.RunPython(tema_to_Tema, migrations.RunPython.noop), migrations.RunPython(clanek_to_Clanek, migrations.RunPython.noop), migrations.RunPython(fix_Clanek_Reseni, migrations.RunPython.noop), + migrations.RunPython(Clanek_Treenody, migrations.RunPython.noop), migrations.RunPython(konfery_rucne, migrations.RunPython.noop), ] From d7898c39b1a1e4b1da137a1931167530c8ac6500 Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Tue, 22 Jun 2021 22:29:11 +0000 Subject: [PATCH 32/55] Spravnejsi vyrobeni treenodu pro clanek --- seminar/migrations/0058_problem_to_uloha_tema_clanek.py | 4 +++- seminar/migrations/0060_spoj_stromy.py | 8 ++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/seminar/migrations/0058_problem_to_uloha_tema_clanek.py b/seminar/migrations/0058_problem_to_uloha_tema_clanek.py index e228f240..14255696 100644 --- a/seminar/migrations/0058_problem_to_uloha_tema_clanek.py +++ b/seminar/migrations/0058_problem_to_uloha_tema_clanek.py @@ -114,7 +114,7 @@ def Clanek_Treenody(apps, schema_editor): TextNode = apps.get_model('seminar', 'TextNode') for cl in Clanek.objects.all(): # Vyrobíme nody: - # Clanek nema vlastni node, ma (prave jedno) Reseni a to ma ReseniNode + # Clanek nema vlastni node, ma (prave jedno) Reseni a to ma text_cely -- ReseniNode reseni = cl.reseni_set.all() if len(reseni) != 1: raise ValueError(f'Clanek {cl.id} ma vic reseni {len(reseni)} ({reseni})') @@ -122,6 +122,8 @@ def Clanek_Treenody(apps, schema_editor): resnode = ReseniNode(reseni=reseni) poskladej_strom(apps, resnode, cl.text_zadani, cl.text_reseni) resnode.save() + reseni.text_cely = resnode + reseni.save() def fix_Clanek_Reseni(apps, schema_editor): Problem = apps.get_model('seminar', 'Problem') diff --git a/seminar/migrations/0060_spoj_stromy.py b/seminar/migrations/0060_spoj_stromy.py index c02b8d12..f6832abd 100644 --- a/seminar/migrations/0060_spoj_stromy.py +++ b/seminar/migrations/0060_spoj_stromy.py @@ -85,8 +85,12 @@ def pokacej_les(apps, schema_editor): # Články for cl in Clanek.objects.filter(cislo = c).order_by('kod'): - clnode = cl.claneknode - pridej_potomka(cnode, clnode) + # Zmena: Clanky nemaji vlastni Node, ale pouziva se ReseniNode v text_cely + reseni = cl.reseni_set.all() + if len(reseni) != 1: + raise ValueError('Clanek ma vic reseni') + resnode = reseni[0].text_cely + pridej_potomka(cnode, resnode) # Konfery for k in Konfera.objects.all(): From 3b646a1099b4ec937854f9ad550cf55ec671426c Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Tue, 22 Jun 2021 23:02:54 +0000 Subject: [PATCH 33/55] Migrace: Reseni.text_cely budiz od vzdycky jen FK na ReseniNode --- seminar/migrations/0049_auto_20190430_2354.py | 5 ----- seminar/migrations/0050_auto_20190510_2228.py | 5 ----- seminar/migrations/0051_resitel_to_osoba.py | 2 +- seminar/migrations/0064_auto_20190610_2358.py | 2 +- seminar/migrations/0066c_reseninode.py | 7 ++++++- seminar/migrations/0077_auto_20200318_2146.py | 2 +- 6 files changed, 9 insertions(+), 14 deletions(-) diff --git a/seminar/migrations/0049_auto_20190430_2354.py b/seminar/migrations/0049_auto_20190430_2354.py index 8abe0460..14fa23d8 100644 --- a/seminar/migrations/0049_auto_20190430_2354.py +++ b/seminar/migrations/0049_auto_20190430_2354.py @@ -480,11 +480,6 @@ class Migration(migrations.Migration): name='resitele', field=models.ManyToManyField(help_text='Seznam autorů řešení', through='seminar.Reseni_Resitele', to='seminar.Resitel', verbose_name='autoři řešení'), ), - migrations.AddField( - model_name='reseni', - name='text_cely', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='reseni_cely_set', to='seminar.Text', verbose_name='Plná verze textu řešení'), - ), migrations.AddField( model_name='reseni', name='text_zkraceny', diff --git a/seminar/migrations/0050_auto_20190510_2228.py b/seminar/migrations/0050_auto_20190510_2228.py index c6ed9f66..a9afc764 100644 --- a/seminar/migrations/0050_auto_20190510_2228.py +++ b/seminar/migrations/0050_auto_20190510_2228.py @@ -23,11 +23,6 @@ class Migration(migrations.Migration): name='osoba', field=models.OneToOneField(help_text='osobní údaje organizátora', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='org', to='seminar.Osoba', verbose_name='osoba'), ), - migrations.AlterField( - model_name='reseni', - name='text_cely', - field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='reseni_cely_set', to='seminar.Text', verbose_name='Plná verze textu řešení'), - ), migrations.AlterField( model_name='resitel', name='osoba', diff --git a/seminar/migrations/0051_resitel_to_osoba.py b/seminar/migrations/0051_resitel_to_osoba.py index 17237bd0..2103a509 100644 --- a/seminar/migrations/0051_resitel_to_osoba.py +++ b/seminar/migrations/0051_resitel_to_osoba.py @@ -81,7 +81,7 @@ def osoba_to_resitel(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('seminar', '0050_auto_20190510_2228'), + ('seminar', '0066c_reseninode'), ] operations = [ diff --git a/seminar/migrations/0064_auto_20190610_2358.py b/seminar/migrations/0064_auto_20190610_2358.py index b72a08a0..78e62862 100644 --- a/seminar/migrations/0064_auto_20190610_2358.py +++ b/seminar/migrations/0064_auto_20190610_2358.py @@ -92,7 +92,7 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='reseni', name='text_cely', - field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='reseni_cely_set', to='seminar.Text', verbose_name='Plná verze textu řešení'), + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='reseni_cely_set', to='seminar.ReseniNode', verbose_name='Plná verze textu řešení'), ), migrations.AlterField( model_name='reseni_resitele', diff --git a/seminar/migrations/0066c_reseninode.py b/seminar/migrations/0066c_reseninode.py index ae3e5a4e..8e3bd3cd 100644 --- a/seminar/migrations/0066c_reseninode.py +++ b/seminar/migrations/0066c_reseninode.py @@ -8,7 +8,7 @@ class Migration(migrations.Migration): dependencies = [ ('contenttypes', '0002_remove_content_type_name'), - ('seminar', '0066b_orgtextnode'), + ('seminar', '0050_auto_20190510_2228'), ] operations = [ @@ -25,5 +25,10 @@ class Migration(migrations.Migration): }, bases=('seminar.treenode',), ), + migrations.AddField( + model_name='reseni', + name='text_cely', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='reseni_cely_set', to='seminar.ReseniNode', verbose_name='Plná verze textu řešení'), + ), ] diff --git a/seminar/migrations/0077_auto_20200318_2146.py b/seminar/migrations/0077_auto_20200318_2146.py index cc0e8c15..5f5f2e26 100644 --- a/seminar/migrations/0077_auto_20200318_2146.py +++ b/seminar/migrations/0077_auto_20200318_2146.py @@ -7,7 +7,7 @@ import django.db.models.deletion class Migration(migrations.Migration): dependencies = [ - ('seminar', '0066c_reseninode'), + ('seminar', '0066b_orgtextnode'), ] operations = [ From ba60f4d3b6b564d5403e5ac2e6a6c8c5dc9b99e6 Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Tue, 22 Jun 2021 23:13:12 +0000 Subject: [PATCH 34/55] Poznamky stripovat. --- db_compare.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/db_compare.py b/db_compare.py index b76a7f5e..6eab9e27 100755 --- a/db_compare.py +++ b/db_compare.py @@ -148,7 +148,13 @@ def check_reseni(): spravna_old = list(filter(lambda o: o['id'] in new_ids, old_res)) res = zip(spravna_old,new_res) for o,n in res: - check_same(o,n,['id', 'forma', 'poznamka', 'timestamp', 'problem_id', 'body', 'cislo_body_id']) + # Tady by se poznamky i timestampy mely zachovat + # Z nejakeho duvodu se ale poznamky lisi ve whitespace, tak je zkontrolujeme separatne + check_same(o,n,['id', 'forma', 'timestamp', 'problem_id', 'body', 'cislo_body_id']) + old_pozn = o['poznamka'].strip() + new_pozn = n['poznamka'].strip() + if old_pozn != new_pozn: + raise ValueError('Poznamky se lisi pro radky {dict(o)} a {dict(n)}') From b2b7b02bf3f1bb2ac5354f1431a5dec6fee7636f Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Tue, 22 Jun 2021 23:29:01 +0000 Subject: [PATCH 35/55] Uprava testu na Clanky --- db_compare.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/db_compare.py b/db_compare.py index cb630fc7..4037ae6d 100755 --- a/db_compare.py +++ b/db_compare.py @@ -448,10 +448,10 @@ def check_res_clanek(): JOIN seminar_problemy AS problem ON problem_ptr_id = problem.id INNER JOIN seminar_hodnoceni AS hodn ON problem.id = hodn.problem_id INNER JOIN seminar_reseni AS rese ON rese.id = hodn.reseni_id - INNER JOIN seminar_nodes_otistene_reseni AS resnode ON resnode.reseni_id = rese.id - INNER JOIN seminar_nodes_treenode AS tn ON resnode.treenode_ptr_id = tn.id - INNER JOIN seminar_nodes_obsah AS son ON son.treenode_ptr_id = tn.first_child_id - INNER JOIN seminar_texty AS text ON text.id = son.text_id + INNER JOIN seminar_nodes_treenode AS tn ON rese.text_cely_id = tn.id + -- Nektere clanky vubec nemely text, tak jim migr 0058 nevyrobila dalsi treenody + LEFT OUTER JOIN seminar_nodes_obsah AS son ON son.treenode_ptr_id = tn.first_child_id + LEFT OUTER JOIN seminar_texty AS text ON text.id = son.text_id ORDER BY problem_ptr_id""" same_fields = ['text_zadani'] @@ -465,6 +465,9 @@ def check_res_clanek(): res = zip(old_res,new_res) for o,n in res: + # text_zadani po novu mohl byt None + if n['text_zadani'] is None: + n['text_zadani'] = '' check_same(o,n, old_fields, new_fields) def check_untyped_problem(): From 9cb27536ab3be8958ea2038921627f9f44a12c77 Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Tue, 29 Jun 2021 17:18:22 +0000 Subject: [PATCH 36/55] Chceme vsechna tematka, ne jen zadana. --- db_compare.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db_compare.py b/db_compare.py index 4037ae6d..968d4c30 100755 --- a/db_compare.py +++ b/db_compare.py @@ -387,7 +387,7 @@ def check_uloha(): def check_tema(): old_query = """SELECT text_zadani, text_reseni, typ, c.rocnik_id AS rocnik_id FROM seminar_problemy - INNER JOIN seminar_cisla AS c ON c.id = cislo_zadani_id + LEFT OUTER JOIN seminar_cisla AS c ON c.id = cislo_zadani_id WHERE typ IN ('tema', 'serial') ORDER BY seminar_problemy.id""" new_query = """SELECT tema_typ, zad_text.na_web AS text_zadani, res_text.na_web AS text_reseni, rn.rocnik_id AS rocnik_id From 39fb659ddb6031fe613bcfca6caa2363aff76672 Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Tue, 29 Jun 2021 17:44:49 +0000 Subject: [PATCH 37/55] Tema ma spoustu nepovinnych parametru, ktere je potreba nejak vyresit. --- db_compare.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/db_compare.py b/db_compare.py index 968d4c30..49a7ab36 100755 --- a/db_compare.py +++ b/db_compare.py @@ -390,7 +390,7 @@ def check_tema(): LEFT OUTER JOIN seminar_cisla AS c ON c.id = cislo_zadani_id WHERE typ IN ('tema', 'serial') ORDER BY seminar_problemy.id""" - new_query = """SELECT tema_typ, zad_text.na_web AS text_zadani, res_text.na_web AS text_reseni, rn.rocnik_id AS rocnik_id + new_query = """SELECT tema_typ, COALESCE(zad_text.na_web, '') AS text_zadani, COALESCE(res_text.na_web, '') AS text_reseni, rn.rocnik_id AS rocnik_id FROM seminar_temata -- Problém: JOIN seminar_problemy AS problem ON problem_ptr_id = problem.id @@ -398,15 +398,15 @@ def check_tema(): -- TvCNode má dva potomky, oba TextNode. První drží původní text zadání, druhý řešení. INNER JOIN seminar_nodes_temavcisle AS tvcn ON tvcn.tema_id = id INNER JOIN seminar_nodes_treenode AS ttn ON tvcn.treenode_ptr_id = ttn.id - INNER JOIN seminar_nodes_treenode AS zad_tn ON ttn.first_child_id = zad_tn.id - INNER JOIN seminar_nodes_treenode AS res_tn ON zad_tn.succ_id = res_tn.id - INNER JOIN seminar_nodes_obsah AS zad_on ON zad_on.treenode_ptr_id = zad_tn.id - INNER JOIN seminar_nodes_obsah AS res_on ON res_on.treenode_ptr_id = res_tn.id - INNER JOIN seminar_texty AS zad_text ON zad_on.text_id = zad_text.id - INNER JOIN seminar_texty AS res_text ON res_on.text_id = res_text.id + LEFT OUTER JOIN seminar_nodes_treenode AS zad_tn ON ttn.first_child_id = zad_tn.id -- jen 33 z nich + LEFT OUTER JOIN seminar_nodes_treenode AS res_tn ON zad_tn.succ_id = res_tn.id -- jen 4 z nich + LEFT OUTER JOIN seminar_nodes_obsah AS zad_on ON zad_on.treenode_ptr_id = zad_tn.id + LEFT OUTER JOIN seminar_nodes_obsah AS res_on ON res_on.treenode_ptr_id = res_tn.id + LEFT OUTER JOIN seminar_texty AS zad_text ON zad_on.text_id = zad_text.id + LEFT OUTER JOIN seminar_texty AS res_text ON res_on.text_id = res_text.id -- vsechny 4 -- Ročník tématu: -- Podle rootu TvCN - INNER JOIN seminar_nodes_rocnik AS rn ON ttn.root_id = rn.treenode_ptr_id + LEFT OUTER JOIN seminar_nodes_rocnik AS rn ON ttn.root_id = rn.treenode_ptr_id -- nic ORDER BY problem_ptr_id""" same_fields = ['text_zadani', 'text_reseni', 'rocnik_id'] From 5ada37c5ed18287b5cff75692cdbe6643ac0c1e2 Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Tue, 29 Jun 2021 17:51:59 +0000 Subject: [PATCH 38/55] Lepsi komentare SQL :-) --- db_compare.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/db_compare.py b/db_compare.py index 49a7ab36..512634e8 100755 --- a/db_compare.py +++ b/db_compare.py @@ -398,15 +398,15 @@ def check_tema(): -- TvCNode má dva potomky, oba TextNode. První drží původní text zadání, druhý řešení. INNER JOIN seminar_nodes_temavcisle AS tvcn ON tvcn.tema_id = id INNER JOIN seminar_nodes_treenode AS ttn ON tvcn.treenode_ptr_id = ttn.id - LEFT OUTER JOIN seminar_nodes_treenode AS zad_tn ON ttn.first_child_id = zad_tn.id -- jen 33 z nich - LEFT OUTER JOIN seminar_nodes_treenode AS res_tn ON zad_tn.succ_id = res_tn.id -- jen 4 z nich + LEFT OUTER JOIN seminar_nodes_treenode AS zad_tn ON ttn.first_child_id = zad_tn.id -- jen 33 z nich ma zadani + LEFT OUTER JOIN seminar_nodes_treenode AS res_tn ON zad_tn.succ_id = res_tn.id -- jen 4 z nich ma reseni LEFT OUTER JOIN seminar_nodes_obsah AS zad_on ON zad_on.treenode_ptr_id = zad_tn.id LEFT OUTER JOIN seminar_nodes_obsah AS res_on ON res_on.treenode_ptr_id = res_tn.id LEFT OUTER JOIN seminar_texty AS zad_text ON zad_on.text_id = zad_text.id LEFT OUTER JOIN seminar_texty AS res_text ON res_on.text_id = res_text.id -- vsechny 4 -- Ročník tématu: - -- Podle rootu TvCN - LEFT OUTER JOIN seminar_nodes_rocnik AS rn ON ttn.root_id = rn.treenode_ptr_id -- nic + -- Podle rootu TvCN to nejde + LEFT OUTER JOIN seminar_nodes_rocnik AS rn ON ttn.root_id = rn.treenode_ptr_id ORDER BY problem_ptr_id""" same_fields = ['text_zadani', 'text_reseni', 'rocnik_id'] From 4186c4b81980aae2419cdb5408bc8dfddef6e633 Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Tue, 29 Jun 2021 18:20:35 +0000 Subject: [PATCH 39/55] Oprava migr 0060 - Tema.temavcislenode je reverse FK, ne one-to-one - Cisla nejde porovnavat - TvCN maji byt ve stromu. --- seminar/migrations/0060_spoj_stromy.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/seminar/migrations/0060_spoj_stromy.py b/seminar/migrations/0060_spoj_stromy.py index f6832abd..59b2943d 100644 --- a/seminar/migrations/0060_spoj_stromy.py +++ b/seminar/migrations/0060_spoj_stromy.py @@ -56,15 +56,19 @@ def pokacej_les(apps, schema_editor): relevantni_temata = Tema.objects.filter(Q(cislo_zadani_old = c) | Q(cislo_reseni_old = c)).order_by('kod') # Téma dáme do prvního čísla, kde se vyskytne for t in relevantni_temata: - tnode = t.temavcislenode + tnodes = t.temavcislenode_set.all() + # Migrujeme, TvCN je jen jedno dohromady + assert(len(tnodes) == 1) + tnode = tnodes[0] + # Zkontrolujeme a preskocime cislo_reseni if t.cislo_zadani_old and t.cislo_reseni_old: - assert(t.cislo_zadani_old <= t.cislo_reseni_old) + assert(t.cislo_zadani_old.rocnik == t.cislo_reseni_old.rocnik + and t.cislo_zadani_old.cislo <= t.cislo_reseni_old.cislo) if t.cislo_reseni_old == c: # Už by mělo být přidané do čísla zadání continue - else: - # Patří sem (buď je to jediné číslo, nebo je to číslo zadání) - pridej_potomka(cnode, tnode) + # Patří sem (buď je to jediné číslo, nebo je to číslo zadání) + pridej_potomka(cnode, tnode) # Úložky (zadání) a pohádky for u in Uloha.objects.filter(cislo_zadani = c).order_by('kod'): From d2d2739882407f8a846ac9771dd875be53169620 Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Tue, 29 Jun 2021 19:06:28 +0000 Subject: [PATCH 40/55] Fix komentare --- db_compare.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db_compare.py b/db_compare.py index 512634e8..783b8124 100755 --- a/db_compare.py +++ b/db_compare.py @@ -405,7 +405,7 @@ def check_tema(): LEFT OUTER JOIN seminar_texty AS zad_text ON zad_on.text_id = zad_text.id LEFT OUTER JOIN seminar_texty AS res_text ON res_on.text_id = res_text.id -- vsechny 4 -- Ročník tématu: - -- Podle rootu TvCN to nejde + -- Podle rootu TvCN LEFT OUTER JOIN seminar_nodes_rocnik AS rn ON ttn.root_id = rn.treenode_ptr_id ORDER BY problem_ptr_id""" From dfb00d6772828010372895e081c2cdce0aa99c8e Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Tue, 29 Jun 2021 19:46:51 +0000 Subject: [PATCH 41/55] fix check_uloha --- db_compare.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/db_compare.py b/db_compare.py index 783b8124..02e01f63 100755 --- a/db_compare.py +++ b/db_compare.py @@ -350,20 +350,21 @@ def check_problem_common(): def check_uloha(): old_query = "SELECT * FROM seminar_problemy WHERE typ = 'uloha' ORDER BY id" - new_query = """SELECT cislo_zadani_id, cislo_reseni_id, problem_ptr_id, max_body, uzt.na_web AS text_zadani, uvt.na_web AS text_reseni + new_query = """SELECT cislo_zadani_id, cislo_reseni_id, problem_ptr_id, max_body, COALESCE(uzt.na_web, '') AS text_zadani, COALESCE(uvt.na_web, '') AS text_reseni, cislo_deadline_id FROM seminar_ulohy -- Problém: JOIN seminar_problemy AS problem ON problem_ptr_id = problem.id -- Text zadání: + -- ZadaniNode a VzorakNode maji existovat vzdy, ale obsah nemusi (pokud ho nemaji) INNER JOIN seminar_nodes_uloha_zadani AS uzn ON problem.id = uzn.uloha_id INNER JOIN seminar_nodes_treenode AS uztn ON uztn.id = uzn.treenode_ptr_id - INNER JOIN seminar_nodes_obsah AS uzo ON uzo.treenode_ptr_id = uztn.first_child_id - INNER JOIN seminar_texty AS uzt ON uzo.text_id = uzt.id + LEFT OUTER JOIN seminar_nodes_obsah AS uzo ON uzo.treenode_ptr_id = uztn.first_child_id + LEFT OUTER JOIN seminar_texty AS uzt ON uzo.text_id = uzt.id -- Text vzoráku: - INNER JOIN seminar_nodes_uloha_zadani AS uvn ON problem.id = uvn.uloha_id + INNER JOIN seminar_nodes_uloha_vzorak AS uvn ON problem.id = uvn.uloha_id INNER JOIN seminar_nodes_treenode AS uvtn ON uvtn.id = uvn.treenode_ptr_id - INNER JOIN seminar_nodes_obsah AS uvo ON uvo.treenode_ptr_id = uvtn.first_child_id - INNER JOIN seminar_texty AS uvt ON uvo.text_id = uvt.id + LEFT OUTER JOIN seminar_nodes_obsah AS uvo ON uvo.treenode_ptr_id = uvtn.first_child_id + LEFT OUTER JOIN seminar_texty AS uvt ON uvo.text_id = uvt.id ORDER BY problem_ptr_id""" @@ -381,7 +382,7 @@ def check_uloha(): for o,n in res: check_same(o,n, old_fields, new_fields) # Datum deadline vypadá prázdně, tak to budeme předpokládat. - if n['datum_deadline'] is not None: + if n['cislo_deadline_id'] is not None: raise ValueError("Úloha má deadline.") def check_tema(): From 7be36d0ec680c33d1382977be9d6d1d148c254b3 Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Tue, 29 Jun 2021 20:15:35 +0000 Subject: [PATCH 42/55] Zbytecne komentare --- seminar/migrations/0058_problem_to_uloha_tema_clanek.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/seminar/migrations/0058_problem_to_uloha_tema_clanek.py b/seminar/migrations/0058_problem_to_uloha_tema_clanek.py index 4bdfbd75..4ef135c4 100644 --- a/seminar/migrations/0058_problem_to_uloha_tema_clanek.py +++ b/seminar/migrations/0058_problem_to_uloha_tema_clanek.py @@ -168,8 +168,6 @@ def tema_to_Tema(apps, schema_editor): TextNode = apps.get_model('seminar', 'TextNode') temata = Problem.objects.filter(Q(typ = 'tema') | Q(typ='serial')) - #temata = Problem.objects.filter(id=635) - #temata = Problem.objects.filter(cislo_zadani_old__id=87) for t in temata: # Vymyslíme správně ročník: if t.cislo_zadani_old is None and t.cislo_reseni_old is None: From e3a5c4bbeb859e91a20ae543b87611a9fc02ae6d Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Tue, 29 Jun 2021 22:22:45 +0000 Subject: [PATCH 43/55] Pred migraci chceme smazat uzivatele bez Organizatoru prekazeli. --- deploy_v2/pre_migration.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/deploy_v2/pre_migration.py b/deploy_v2/pre_migration.py index 45af8dc8..53f58d95 100755 --- a/deploy_v2/pre_migration.py +++ b/deploy_v2/pre_migration.py @@ -23,5 +23,16 @@ def smaz_zle_clanky(): # Nakonec i ty clanky samotne cursor.execute('DELETE FROM seminar_problemy WHERE id IN (1981, 1970, 2222);') +def smaz_divne_uzivatele(): + # U techto uzivatelu neexistuje Organizator s nimi spojeny + # Takze pak delaji akorat neporadek + with connection.cursor() as cursor: + # Jeste je potreba zrusit vazby + cursor.execute('UPDATE django_comments SET user_id = NULL WHERE user_id = 34;') + cursor.execute('UPDATE seminar_problemy SET autor_id = NULL WHERE autor_id = 34;') + cursor.execute('DELETE FROM django_admin_log WHERE user_id = 34;') + cursor.execute('DELETE FROM auth_user_groups WHERE user_id = 34;') + cursor.execute('DELETE FROM auth_user WHERE id IN (34, 40, 30, 50, 54, 58, 43);') smaz_zle_clanky() +smaz_divne_uzivatele() From c5620e0fcad88a735288f255ef3be8aca695e7cc Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Tue, 29 Jun 2021 22:32:52 +0000 Subject: [PATCH 44/55] Fix query opravovatele --- db_compare.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/db_compare.py b/db_compare.py index 02e01f63..728a38d5 100755 --- a/db_compare.py +++ b/db_compare.py @@ -333,13 +333,15 @@ def check_problem_common(): # Opravovatelé old_query = "SELECT id, opravovatel_id FROM seminar_problemy" - new_query = "SELECT problem_id, opravovatel_id FROM seminar_problemy_opravovatele" + new_query = "SELECT problem_id, organizator_id FROM seminar_problemy_opravovatele" # Simple cursors #oldcur = oldconn.cursor() - old_results = oldcur.execute(old_query).fetchall() + oldcur.execute(old_query) + old_results = oldcur.fetchall() #newcur = newconn.cursor() - new_results = newcur.execute(new_query).fetchall() + newcur.execute(new_query) + new_results = newcur.fetchall() for oldr in old_results: if oldr not in new_results: From b8cded675ac44098a93d055d59ded9077e562147 Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Tue, 29 Jun 2021 22:45:35 +0000 Subject: [PATCH 45/55] Org postaru je user --- db_compare.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/db_compare.py b/db_compare.py index 728a38d5..a3ba908c 100755 --- a/db_compare.py +++ b/db_compare.py @@ -332,7 +332,9 @@ def check_problem_common(): check_same(o,n, old_fields, new_fields) # Opravovatelé - old_query = "SELECT id, opravovatel_id FROM seminar_problemy" + # Po staru byli opravovatele organizatori, takze je potreba je dohledat. + old_query = """SELECT seminar_problemy.id, org.id AS opravovatel_id FROM seminar_problemy + JOIN seminar_organizator AS org ON seminar_problemy.opravovatel_id = org.user_id;""" new_query = "SELECT problem_id, organizator_id FROM seminar_problemy_opravovatele" # Simple cursors From 7bb79ce56f8f3cae4c1b4efc6e8bccb268d35c4b Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Wed, 30 Jun 2021 00:49:42 +0000 Subject: [PATCH 46/55] Oprava check_pohadka --- db_compare.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/db_compare.py b/db_compare.py index a3ba908c..3cdee268 100755 --- a/db_compare.py +++ b/db_compare.py @@ -302,7 +302,8 @@ def check_pohadka(): if get_user_id_for_org_id(n['autor_id']) != o['autor_id']: raise ValueError("Nesedi autori u pohadky") # Správné úlohy - spravny_klic = 'uloha_pred' if o['pred'] else 'uloha_po' + # NOTE: o['pred'] rika, zda je pohadka pred ulohou, nikoliv zda je relevantni uloha pred pohadkou! + spravny_klic = 'uloha_po' if o['pred'] else 'uloha_pred' if o['uloha_id'] != n[spravny_klic]: raise ValueError(f"Pohádka přidružená ke špatné úloze! old: {o['uloha_id']}, new: {n[spravny_klic]}, pozice: {spravny_klic}") From 7f89af129f31e5973ad578b3bcf074c5c305c919 Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Wed, 30 Jun 2021 00:59:02 +0000 Subject: [PATCH 47/55] m0060: likvidace sirotku ve stromu --- db_compare.py | 4 ++-- mamweb/settings_local.py | 14 +++++++------- seminar/migrations/0060_spoj_stromy.py | 12 ++++++++++-- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/db_compare.py b/db_compare.py index 3cdee268..f960492a 100755 --- a/db_compare.py +++ b/db_compare.py @@ -3,8 +3,8 @@ import psycopg2 import psycopg2.extras -OLD_DB = "mam_old" -NEW_DB = "mamweb" +OLD_DB = "mam-prod" +NEW_DB = "mam-test" oldconn = psycopg2.connect(f"dbname={OLD_DB}") newconn = psycopg2.connect(f"dbname={NEW_DB}") diff --git a/mamweb/settings_local.py b/mamweb/settings_local.py index 0aadd27e..2ba43478 100644 --- a/mamweb/settings_local.py +++ b/mamweb/settings_local.py @@ -39,13 +39,13 @@ DATABASES = { 'NAME': os.path.join(BASE_DIR, 'db-local.sqlite3'), } } -#DATABASES = { -# 'default': { -# 'ENGINE': 'django.db.backends.postgresql_psycopg2', -# 'NAME': 'mam_local', -# 'USER': 'mam', -# }, -#} +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.postgresql_psycopg2', + 'NAME': 'mam-test', + 'USER': 'kam', + }, +} # LOGGING LOGGING = { diff --git a/seminar/migrations/0060_spoj_stromy.py b/seminar/migrations/0060_spoj_stromy.py index 59b2943d..d0826ca1 100644 --- a/seminar/migrations/0060_spoj_stromy.py +++ b/seminar/migrations/0060_spoj_stromy.py @@ -6,6 +6,15 @@ from django.db import migrations from django.db.models import Q +def nastav_koren(koren, node): + node.root = koren + node.save() + + if node.succ: + nastav_koren(koren, node.succ) + if node.first_child: + nastav_koren(koren, node.first_child) + def pridej_potomka(rodic, potomek): # Daný vrchol bude posledním potomkem rodiče uz_ma_deti = False @@ -23,8 +32,7 @@ def pridej_potomka(rodic, potomek): posledni = posledni.succ # Nastavíme kořen: - potomek.root = rodic.root - potomek.save() + nastav_koren(rodic.root, potomek) # Připojíme vrchol: if uz_ma_deti: From df682e0630992b63449ffb242a8fbb8894ef1b96 Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Wed, 30 Jun 2021 01:01:35 +0000 Subject: [PATCH 48/55] Revert "m0060: likvidace sirotku ve stromu" This reverts commit 7f89af129f31e5973ad578b3bcf074c5c305c919. Pushuju blbosti :-) --- db_compare.py | 4 ++-- mamweb/settings_local.py | 14 +++++++------- seminar/migrations/0060_spoj_stromy.py | 12 ++---------- 3 files changed, 11 insertions(+), 19 deletions(-) diff --git a/db_compare.py b/db_compare.py index f960492a..3cdee268 100755 --- a/db_compare.py +++ b/db_compare.py @@ -3,8 +3,8 @@ import psycopg2 import psycopg2.extras -OLD_DB = "mam-prod" -NEW_DB = "mam-test" +OLD_DB = "mam_old" +NEW_DB = "mamweb" oldconn = psycopg2.connect(f"dbname={OLD_DB}") newconn = psycopg2.connect(f"dbname={NEW_DB}") diff --git a/mamweb/settings_local.py b/mamweb/settings_local.py index 2ba43478..0aadd27e 100644 --- a/mamweb/settings_local.py +++ b/mamweb/settings_local.py @@ -39,13 +39,13 @@ DATABASES = { 'NAME': os.path.join(BASE_DIR, 'db-local.sqlite3'), } } -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': 'mam-test', - 'USER': 'kam', - }, -} +#DATABASES = { +# 'default': { +# 'ENGINE': 'django.db.backends.postgresql_psycopg2', +# 'NAME': 'mam_local', +# 'USER': 'mam', +# }, +#} # LOGGING LOGGING = { diff --git a/seminar/migrations/0060_spoj_stromy.py b/seminar/migrations/0060_spoj_stromy.py index d0826ca1..59b2943d 100644 --- a/seminar/migrations/0060_spoj_stromy.py +++ b/seminar/migrations/0060_spoj_stromy.py @@ -6,15 +6,6 @@ from django.db import migrations from django.db.models import Q -def nastav_koren(koren, node): - node.root = koren - node.save() - - if node.succ: - nastav_koren(koren, node.succ) - if node.first_child: - nastav_koren(koren, node.first_child) - def pridej_potomka(rodic, potomek): # Daný vrchol bude posledním potomkem rodiče uz_ma_deti = False @@ -32,7 +23,8 @@ def pridej_potomka(rodic, potomek): posledni = posledni.succ # Nastavíme kořen: - nastav_koren(rodic.root, potomek) + potomek.root = rodic.root + potomek.save() # Připojíme vrchol: if uz_ma_deti: From d22f8ec13687efe22ed208a0780527bfbb3f8381 Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Wed, 30 Jun 2021 01:04:48 +0000 Subject: [PATCH 49/55] m0060: likvidace potomku bez blbosti kolem --- seminar/migrations/0060_spoj_stromy.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/seminar/migrations/0060_spoj_stromy.py b/seminar/migrations/0060_spoj_stromy.py index 59b2943d..d0826ca1 100644 --- a/seminar/migrations/0060_spoj_stromy.py +++ b/seminar/migrations/0060_spoj_stromy.py @@ -6,6 +6,15 @@ from django.db import migrations from django.db.models import Q +def nastav_koren(koren, node): + node.root = koren + node.save() + + if node.succ: + nastav_koren(koren, node.succ) + if node.first_child: + nastav_koren(koren, node.first_child) + def pridej_potomka(rodic, potomek): # Daný vrchol bude posledním potomkem rodiče uz_ma_deti = False @@ -23,8 +32,7 @@ def pridej_potomka(rodic, potomek): posledni = posledni.succ # Nastavíme kořen: - potomek.root = rodic.root - potomek.save() + nastav_koren(rodic.root, potomek) # Připojíme vrchol: if uz_ma_deti: From 8e47df286574f2029c67c937ecdec0598154ce53 Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Wed, 30 Jun 2021 04:03:57 +0200 Subject: [PATCH 50/55] =?UTF-8?q?Lep=C5=A1=C3=AD=20"Moje=20probl=C3=A9my"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/views/views_all.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/seminar/views/views_all.py b/seminar/views/views_all.py index 5c51c517..a05ac356 100644 --- a/seminar/views/views_all.py +++ b/seminar/views/views_all.py @@ -846,17 +846,17 @@ class OrgoRozcestnikView(TemplateView): u = self.request.user os = s.Osoba.objects.get(user=u) organizator = s.Organizator.objects.get(osoba=os) - temata_garant = s.Tema.objects.filter(garant=organizator, - rocnik=aktualni_rocnik) - #FIXME: přidat opravovatel, stav='STAV_ZADANY' - ulohy_garant = s.Uloha.objects.filter(garant=organizator, - cislo_zadani__rocnik=aktualni_rocnik) - clanky_garant = s.Clanek.objects.filter(garant=organizator, - cislo__rocnik=aktualni_rocnik) - - context['temata'] = temata_garant - context['ulohy'] = ulohy_garant - context['clanky'] = clanky_garant + #FIXME: přidat stav='STAV_ZADANY' + temata = s.Tema.objects.filter(Q(garant=organizator) | Q(autor=organizator) | Q(opravovatele__in=[organizator]), + rocnik=aktualni_rocnik).distinct() + ulohy = s.Uloha.objects.filter(Q(garant=organizator) | Q(autor=organizator) | Q(opravovatele__in=[organizator]), + cislo_zadani__rocnik=aktualni_rocnik).distinct() + clanky = s.Clanek.objects.filter(Q(garant=organizator) | Q(autor=organizator) | Q(opravovatele__in=[organizator]), + cislo__rocnik=aktualni_rocnik).distinct() + + context['temata'] = temata + context['ulohy'] = ulohy + context['clanky'] = clanky context['organizator'] = organizator return context From fcfabb1bf4f418cf8f3bb70bd6e0d1b36aa8b63e Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Wed, 30 Jun 2021 04:04:14 +0200 Subject: [PATCH 51/55] =?UTF-8?q?Orgorozcestn=C3=ADk:=20po=C4=8Det=20neopr?= =?UTF-8?q?aven=C3=BDch=20=C5=99e=C5=A1en=C3=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/templates/seminar/orgorozcestnik.html | 7 ++++++- seminar/views/views_all.py | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/seminar/templates/seminar/orgorozcestnik.html b/seminar/templates/seminar/orgorozcestnik.html index 3ad954a1..c24ca05d 100644 --- a/seminar/templates/seminar/orgorozcestnik.html +++ b/seminar/templates/seminar/orgorozcestnik.html @@ -27,7 +27,12 @@
  • přidat pdf k opravám
  • -
  • zadávání bodů
  • +
  • + zadávání bodů + {% if pocet_neobodovanych_reseni > 0 or pocet_reseni_mimo_cislo > 0 %} + ({{pocet_neobodovanych_reseni}} řešení nemá body, {{pocet_reseni_mimo_cislo}} není v žádném čísle!) + {% endif %} +
  • poslední vydané číslo

  • diff --git a/seminar/views/views_all.py b/seminar/views/views_all.py index a05ac356..e10aad6c 100644 --- a/seminar/views/views_all.py +++ b/seminar/views/views_all.py @@ -843,6 +843,9 @@ class OrgoRozcestnikView(TemplateView): # pokud nechceme haluzit kód (= poradi) dalšího čísla, bude asi potřeba jít # přes treenody (a dát si přitom pozor na MezicisloNode) + context['pocet_neobodovanych_reseni'] = s.Hodnoceni.objects.filter(body__isnull=True).count() + context['pocet_reseni_mimo_cislo'] = s.Hodnoceni.objects.filter(cislo_body__isnull=True).count() + u = self.request.user os = s.Osoba.objects.get(user=u) organizator = s.Organizator.objects.get(osoba=os) From 303b6bab4ae261d39660ac21cb9c75fa85c9cebc Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Wed, 30 Jun 2021 04:16:29 +0200 Subject: [PATCH 52/55] =?UTF-8?q?Tabulka=20odevzdan=C3=BDch=20=C5=99e?= =?UTF-8?q?=C5=A1en=C3=AD:=20filtr=20podle=20neobodovan=C3=BDch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/forms.py | 2 ++ seminar/templates/seminar/odevzdavatko/tabulka.html | 1 + seminar/views/odevzdavatko.py | 4 ++++ 3 files changed, 7 insertions(+) diff --git a/seminar/forms.py b/seminar/forms.py index 2944ef52..03dc645d 100644 --- a/seminar/forms.py +++ b/seminar/forms.py @@ -404,6 +404,7 @@ class OdevzdavatkoTabulkaFiltrForm(forms.Form): 'problemy': cls.PROBLEMY_MOJE, 'reseni_od': terminy[-2], 'reseni_do': terminy[-1], + 'neobodovane': False, } return initial @@ -426,3 +427,4 @@ class OdevzdavatkoTabulkaFiltrForm(forms.Form): reseni_od = forms.DateField(input_formats=[DATE_FORMAT]) reseni_do = forms.DateField(input_formats=[DATE_FORMAT]) + neobodovane = forms.BooleanField(required=False) diff --git a/seminar/templates/seminar/odevzdavatko/tabulka.html b/seminar/templates/seminar/odevzdavatko/tabulka.html index 26a6f922..23b75d9c 100644 --- a/seminar/templates/seminar/odevzdavatko/tabulka.html +++ b/seminar/templates/seminar/odevzdavatko/tabulka.html @@ -9,6 +9,7 @@ {{ filtr.problemy }} Od: {{ filtr.reseni_od }} Do: {{ filtr.reseni_do }} +🔨? {{ filtr.neobodovane }} diff --git a/seminar/views/odevzdavatko.py b/seminar/views/odevzdavatko.py index 09b4293f..e0d98184 100644 --- a/seminar/views/odevzdavatko.py +++ b/seminar/views/odevzdavatko.py @@ -59,12 +59,14 @@ class TabulkaOdevzdanychReseniView(ListView): problemy = fcd["problemy"] reseni_od = fcd["reseni_od"] reseni_do = fcd["reseni_do"] + jen_neobodovane = fcd["neobodovane"] else: initial = FiltrForm.gen_initial() resitele = initial['resitele'] problemy = initial['problemy'] reseni_od = initial['reseni_od'][0] reseni_do = initial['reseni_do'][0] + jen_neobodovane = initial["neobodovane"] # Filtrujeme! @@ -87,6 +89,8 @@ class TabulkaOdevzdanychReseniView(ListView): self.problemy = self.problemy.non_polymorphic() self.reseni = self.reseni.filter(cas_doruceni__date__gte=reseni_od, cas_doruceni__date__lte=reseni_do) + if jen_neobodovane: + self.reseni = self.reseni.filter(hodnoceni__body__isnull=True) def get_queryset(self): self.inicializuj_osy_tabulky() From df14d03fc27b8574f318674cb65e2faf4879c01c Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Wed, 30 Jun 2021 23:48:55 +0000 Subject: [PATCH 53/55] Par drobnych zmen --- db_compare.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/db_compare.py b/db_compare.py index 3cdee268..a45406be 100755 --- a/db_compare.py +++ b/db_compare.py @@ -78,7 +78,7 @@ def check_resitel(): 'prijmeni', 'user_id', 'pohlavi_muz', - #'email', #TODO: potřeba dořešit, protože merge řešitele a organizátora + #'email', #vyreseno separatne 'telefon', 'datum_narozeni', 'datum_souhlasu_udaje', @@ -99,6 +99,8 @@ def check_resitel(): fields = fields_keep+fields_osoba for o,n in res: check_same(o,n,fields) + if o['email'] != n['email'] and o['email'] != '': + print(f"WARNING: Emails differ: old: {o['email']}, new: {n['email']}") def check_reseni(): # Migrace 0058 zamerne meni (zmensuje) pocet reseni, aby kazdy clanek mel @@ -183,7 +185,7 @@ def check_organizator(): # Migrace prirazuje aktualni casovou zonu, takze chceme tady rucne vynutit CET. from datetime import timedelta, timezone cet = timezone(timedelta(hours=1)) - if o['organizuje_do_roku'] is None and n['organizuje_do'] is None: + if o['organizuje_od_roku'] is None and n['organizuje_od'] is None: pass elif o['organizuje_od_roku'] != n['organizuje_od'].astimezone(cet).year: raise ValueError(f'Not matching organizuje_od for org id={o["id"]}: old {o["organizuje_od_roku"]}, new {n["organizuje_od"]}') @@ -430,7 +432,7 @@ def check_tema(): def check_konfera(): old_query = "SELECT * FROM seminar_problemy WHERE typ = 'konfera'" - new_query = "SELECT * FROM seminar_konfera AS k JOIN seminar_problemy AS problem ON k.problem_ptr_id = problem.id" + new_query = "SELECT * FROM seminar_konfera" oldcur.execute(old_query) newcur.execute(new_query) From dde97d7ab5cb635aef8a5c8083c80fc94e6f36a8 Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Wed, 30 Jun 2021 23:52:38 +0000 Subject: [PATCH 54/55] Zapomenuta migrace: nepovinna prezdivka --- seminar/migrations/0094_auto_20210701_0149.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 seminar/migrations/0094_auto_20210701_0149.py diff --git a/seminar/migrations/0094_auto_20210701_0149.py b/seminar/migrations/0094_auto_20210701_0149.py new file mode 100644 index 00000000..8a6b0515 --- /dev/null +++ b/seminar/migrations/0094_auto_20210701_0149.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.24 on 2021-06-30 23:49 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0093_auto_20210330_2105'), + ] + + operations = [ + migrations.AlterField( + model_name='osoba', + name='prezdivka', + field=models.CharField(blank=True, max_length=256, null=True, verbose_name='přezdívka'), + ), + ] From a19e5b7c73360fd8730ba07f0c9080f8e5c713db Mon Sep 17 00:00:00 2001 From: "Pavel Turinsky (DebianVM @ Zr)" Date: Wed, 30 Jun 2021 23:59:18 +0000 Subject: [PATCH 55/55] Dalsich par zmen --- db_compare.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/db_compare.py b/db_compare.py index a45406be..031bde86 100755 --- a/db_compare.py +++ b/db_compare.py @@ -456,7 +456,8 @@ def check_res_clanek(): JOIN seminar_problemy AS problem ON problem_ptr_id = problem.id INNER JOIN seminar_hodnoceni AS hodn ON problem.id = hodn.problem_id INNER JOIN seminar_reseni AS rese ON rese.id = hodn.reseni_id - INNER JOIN seminar_nodes_treenode AS tn ON rese.text_cely_id = tn.id + INNER JOIN seminar_nodes_otistene_reseni AS rn ON rese.text_cely_id = rn.treenode_ptr_id -- Tenhle radek neni potreba, ale ujistuje se mj. o spravnem typu TreeNode. + INNER JOIN seminar_nodes_treenode AS tn ON rn.treenode_ptr_id = tn.id -- Nektere clanky vubec nemely text, tak jim migr 0058 nevyrobila dalsi treenody LEFT OUTER JOIN seminar_nodes_obsah AS son ON son.treenode_ptr_id = tn.first_child_id LEFT OUTER JOIN seminar_texty AS text ON text.id = son.text_id @@ -477,6 +478,7 @@ def check_res_clanek(): if n['text_zadani'] is None: n['text_zadani'] = '' check_same(o,n, old_fields, new_fields) + assert(o['text_reseni'] == '') def check_untyped_problem(): old_query = "SELECT * FROM seminar_problemy WHERE typ NOT IN ('uloha', 'tema', 'serial', 'konfera', 'org-clanek', 'res-clanek')"