Neulich hat
Hanno bei
uns das MediaWiki auf eine neue Version geupdatet. Es war von 1.4.15 auf 1.6.8. Daraufhin war die Datenbasis mysteriös kaputt. Genauer gesagt haben manche Seiten gefehlt, manche waren steinalt und manche noch aktuell.
Zur Sicherheit habe ich dann von neuem die Update-Prozedur nochmal mit einem alten Backup der Datenbank nachgestellt und kam zu exakt demselben Ergebnis.
Nach einiger Zeit an Recherche in den Untiefen der Datenbank von MediaWiki habe ich festegstellt, dass sich einiges am Datenbank-Schema geändert hat. Bisher waren die Tabellen 'old' und 'cur' für die Inhalte zuständig, dort wurden die alten resp. die aktuellste Version jeder Seite aufbewahrt.
Im neuen Schema gibt es jetzt (eigentlich logischer) die Tabellen 'page', 'revision' und 'text', die Informationen zu den Unterschiedlichen Seiten, deren Versionen und den entsprechenden Texten speichern. 'page' verlinkt dabei immer auf die aktuelle Revision einer Seite.
Das Debugging hat nun ergeben, dass der update-Wizzard von MediaWiki aus irgendwelchen unerfindlichen Gründen die Datenbank nicht korrekt konvertiert hat. Es wurden Seiten vergessen oder alte Versionen als aktuell markiert.
Als Lösung habe ich ein Programm geschrieben, das die alte 'cur'-Tabelle ausliest und im neuen Datenbank-Schema eine neue Version jeder Seite mit dem Inhalt aus der alten Tabelle erstellt.
Der Einfachkeit halber konvertiere ich nur Artikel im Namespace 0, also normale Artikel.
Hier nochmal die ausdrückliche Warnung: Das Script ist aus der Notwendigkeit entstanden, sinnvolle Schleifen zu wollen. Es wurde am Objekt entwickelt und hat
einmal bei mir funktioniert. Wer es einsetzen will, muss sich im Klaren sein, was es tut.
Es kann auch sein, dass Einrückung und/oder Zeilenumbrüche hier anders dargestellt sind als es Python erfordert. Keine Gewähr dafür. :)
#!/usr/bin/python
# - coding: utf8 -
import MySQLdb
db = MySQLdb.connect(user='...', passwd='...', db='wiki')
sql = db.cursor(MySQLdb.cursors.DictCursor)
sql.execute("SELECT * FROM cur WHERE `cur_namespace`=0;")
res = sql.fetchall()
for i in res:
for s in i.keys():
if type(i[s]) == str:
i[s] = db.escape_string(i[s])
sql.execute("INSERT INTO `text` (old_namespace, old_title, old_text, old_user, old_user_text, old_timestamp, old_minor_edit, inverse_timestamp) VALUES (%(cur_namespace)i, '%(cur_title)s', '%(cur_text)s', %(cur_user)i, '%(cur_user_text)s', '%(cur_timestamp)s', %(cur_minor_edit)i, '%(inverse_timestamp)s')" % i)
text_id = sql.lastrowid
page_id = None
sql.execute("SELECT page_id FROM page WHERE page_title='%s' LIMIT 1" % i['cur_title'])
if sql.rowcount == 0:
sql.execute("INSERT INTO page (page_namespace, page_title, page_random, page_len) VALUES (0, '%s', %f, %i)" % (i['cur_title'], i['cur_random'], len(i['cur_text'])))
page_id = sql.lastrowid
else:
r1 = sql.fetchone()
page_id = r1['page_id']
sql.execute("INSERT INTO revision (rev_page, rev_user, rev_user_text, rev_timestamp, rev_text_id) VALUES (%i, %i, '%s', '%s', %i)" % (page_id, i['cur_user'], i['cur_user_text'], i['cur_timestamp'], text_id))
rev_id = sql.lastrowid
sql.execute("UPDATE page SET page_latest = %i WHERE page_id = %i" % (rev_id, page_id))
sql.execute('COMMIT;')