Spojovani reseni pro Clanky, aby mely jen jedno...
This commit is contained in:
		
							parent
							
								
									36c3cc6814
								
							
						
					
					
						commit
						b381f46b23
					
				
					 2 changed files with 73 additions and 19 deletions
				
			
		|  | @ -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' | ||||
|  |  | |||
|  | @ -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), | ||||
| 	] | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Pavel Turinsky (DebianVM @ Zr)
						Pavel Turinsky (DebianVM @ Zr)