Blogini siirtyi nyt MongoDB:hen. Vanhan sisällön siirto MySQL:stä sujui pääosin ongelmitta. Muutamia relaatioita piti poistaa ja korvata EmbeddedModelField-objekteilla.

Tein siirron dumppaamalla ensin vanhan sisällön MySQL:stä ./manage.py dumpdata -komennolla JSON-tiedostoihin. Sitten ajoin pienen skriptin, joka muutti objektien numeeriset pk-kentät ja foreignkey-relaatiot MongoDB:n ObjectId-muotoon. Lopuksi latasin konvertoidun sisällön ./manage.py loaddata -komennolla MongoDB:hen.

ObjectId-konversio oli ajatukseltaan tällainen, eli ObjectId:t muodostettiin aikaleimasta ja MySQL:n aiemmasta numeerisesta primarykeystä:

pk = item['pk']
if 'created' in item['fields']:
    ts = time.mktime(datetime.strptime(item['fields']['created'], '%Y-%m-%d %H:%M:%S').timetuple())
item['pk'] = '%08x%06x%010x' % (ts, machine, int(pk))

Hankalin osuus oli kommentointi, joka perustui aiemmin Djangon sisäänrakennettuun comments-ominaisuuteen ja siihen model inheritancella tehtyihin laajennuksiin. Korvasin ne omalla implementaatiolla, johon tarvittiin muutama kymmentä riviä Python-koodia. Pienenä haittapuolena tuli se, että kommenttien ID:t vaihtuivat MongoDB:n ObjectId:iksi ja RSS-feedin pointterit menivät nollille.

Toinen haaste olivat kategoriat, jotka oli toteutettu ManyToManyField-relaatioina. Päädyin irrottamaan kategoriat omaksi ArticleCategory-objektikseen, jota voi kätevästi hallita Djangon TabularInlineillä ylläpidosta, sekä lisäämään artikkeleihin ListField(EmbeddedModelField(Category)) -kentän, joka voidaan indeksoida hakuja varten. Kun Djangon ylläpidosta lisää artikkeleihin kategorioita, ne päivitetään automaattisesti save()-metodissa noihin ListFieldeihin.