Djnago / djongo Jak migrovat po vytvoření jedinečného indexu v mongo db

Foto Faisal M na Unsplash

Pro vývoj serveru používám zásobník Django / djongo / mongodb / drf. samotný server je centralizovaným správcem procházení, takže více instancí prolézacího modulu může konzistentně ukládat procházená data zpráv.

Při mé konkrétní příležitosti čelím tomuto konkrétnímu problému. Definoval jsem model s názvem article_url, který nebyl nakonfigurován jako jedinečný. a přidal validátor pro article_url, aby nebyl konfliktní. (v serializátoru společnosti drf), protože validátor je nákladná operace a při manipulaci s rozsáhlými daty je třeba tomu zabránit ve vrstvě databáze

můj původní model vypadal,

z importních modelů djongo
třída RawNews (models.Model): třída Meta: db_table = 'raw' _id = models.ObjectIdField () time = models.DateTimeField () title = models.CharField (max_length = 200) article_url = models.URLField (max_length = 200) body_html = models.TextField ()

poté, co jsem se změnil (přidáno jedinečné = true do pole article_url)

z importních modelů djongo
třída RawNews (models.Model): třída Meta: db_table = 'raw' _id = models.ObjectIdField () time = models.DateTimeField () title = models.CharField (max_length = 200) article_url = models.URLField (max_length = 200, unique = True) body_html = models.TextField ()

pak,

python manage.py makemigrations -> funguje dobře jako obvykle

python manage.py migrate ->

Chyba Pymongo: {'ok': 0.0, 'errmsg': 'Kolekce duplikátů klíčů E11000: db.raw index: raw_article_url_uniq duplikát klíče: {article_url: “https: // ~…

Chcete-li to vyřešit, budete muset odstranit konflikt pro klíč, který chcete vytvořit jedinečný ručně, a spusťte migraci znovu.

Pojďme na to!

TL; DR

  • jak vytvořit nový index jako jedinečný v kolekci mongodb
  • jak odstranit konfliktní data, aby bylo možné vytvořit jedinečný index bez chyb.
  • konečně, jak migrovat django / djongo / mongodb projekt s novým modelem jedinečného pole

jak vytvořit nový index jako jedinečný v kolekci mongodb

db.raw.ensureIndex ({article_url: 1}, {unique: true, dropDups: true})

výše uvedený příkaz by měl fungovat, pouze pokud používáte mongodb 2.X

Pokud používáte mongodb 3.X, obdržíte níže uvedenou zprávu.

{"ok": 0, "errmsg": "Kolekce duplikátů klíčů E11000: db.raw index: article_url_1 duplicitní klíč: {article_url:" https: // ~~~ "}", "code": 11000, "codeName ":" DuplicateKey "," keyPattern ": {" article_url ": 1}," keyValue ": {" article_url ":" https: // ~~~ "}}
Protože mongodb 3.X dropDups (duplikáty drop) je zastaralý a ignorován.

oficiální dokument říká, že je v pořádku, ale není (dokument není aktualizován od roku 2020.2). Takže výše uvedený příkaz bude zastaralý a budete muset napsat

db.raw.ensureIndex ({article_url: 1}, {unique: true})

stále budete dostávat stejnou chybu, budete muset nejprve odstranit konfliktní klíče ručně, abyste vytvořili jedinečné indexy. (postupujte níže)

jak odstranit konfliktní data, aby mohl být jedinečný index vytvořen bezchybně.

db.raw.find ({}, {article_url: 1}). sort ({_ id: 1}). forEach (function (doc) {db.raw.remove ({_ id: {$ gt: doc._id}, article_url: doc.article_url});})

tato operace může chvíli trvat v závislosti na velikosti vaší sbírky. Jakmile je tento krok konkurenční, můžete nyní pro klíč vytvořit jedinečný index (znovu spustit příkaz nad oddílem)

misc :: další příkazy

// seznam vytvořil index pro kolekci 'raw' <- nahraďte tento db.raw.getIndexes ()
// odebrat index vytvořený s názvem indexu (seznam můžete zobrazit pomocí výše uvedeného příkazu) db.raw.dropIndex ( )

Reference

https://docs.mongodb.com/manual/tutorial/manage-indexes/