sql >> Databáze >  >> NoSQL >> MongoDB

Vývoj databáze Python a MongoDB

Jak bylo zmíněno v první části této série:Programování databáze Python s MongoDB, modul Python PyMongo je vyžadováno, aby Python mohl komunikovat s databází MongoDB. Chcete-li to nainstalovat, použijte příkaz na příkazovém řádku systému Windows:

pip3 install pymongo

Instalace PyMonga by měla produkovat výstup podobný tomu, který je zobrazen níže:

Obrázek 1 – Instalace modulu PyMongo

V závislosti na konfiguraci Pythonu, další modul s názvem dnspython může být také nutné:

pip3 install dnspython

Obrázek 2 – Instalace dnspythonu modul

Jak vložit data do MongoDB pomocí Pythonu

Níže uvedený kód vytvoří 15 náhodně vygenerovaných Umělců a dvě alba pro každý z nich:

# bad-band-name-maker-nosql.py

import sys
import random
import pymongo

part1 = ["The", "Uncooked", "Appealing", "Larger than Life", "Drooping", "Unwell", "Atrocious", "Glossy", "Barrage", "Unlawful"]
part2 = ["Defeated", "Hi-Fi", "Extraterrestrial", "Adumbration", "Limpid", "Looptid", "Cromulent", "Unsettled", "Soot", "Twinkle"]
part3 = ["Brain", "Segment", "\"Audio\"", "Legitimate Business", "\"Bob\"", "Sound", "Canticle", "Monsoon", "Preserves", "\"Cacophony\""]

part4 = ["Cougar", "Lion", "Lynx", "Ocelot", "Puma", "Jaguar", "Panther"]
part5 = ["Fodder", "Ersatz Goods", "Leftovers", "Infant Formula", "Mush", "Smoothie", "Milkshakes"]


def main(argv):
  # Connect to the RazorDemo database.
  client = pymongo.MongoClient("mongodb+srv://yourUser:[email protected]/RazorDemo?retryWrites=true&w=majority", 
    serverSelectionTimeoutMS=5000)
  artistsCollection = client["RazorDemo"]["Artists"]
  albumsCollection = client["RazorDemo"]["Albums"]

  # Generate 15 bad band names, and try to keep them unique.
  previousNames = ""
  nameCount = 0
  artistJson = []
  while (nameCount < 16):
    rand1 = random.randrange(0, 9)
    rand2 = random.randrange(0, 9)
    rand3 = random.randrange(0, 9)
    badName = part1[rand1] + ' ' + part2[rand2] + ' ' + part3[rand3]
    
    # Unlike with SQL-oriented databases, MongoDB allows for the insertion of multiple documents in a single statement.
    # In this case, the code will build a JSON list of all the band names to be inserted in a one fell swoop.
    if ("|" + previousNames + "|").find("|" + badName + "|") == -1: 
      #print ("Band name [" + str(nameCount) + "] is [" + badName + "]")
      # Don't forget to escape quotation marks!
      
      jsonEntry = { "artist_name" : badName }
      artistJson.append(jsonEntry)
      
      # Because there are no foreign key rules, the album names can be created 
      # and committed to the database before the artist names have been created.
      albumJson = []
      for y in range(1, 3):
        rand4 = random.randrange(0, len(part4))
        rand5 = random.randrange(0, len(part5))
        
        # No checks for uniqueness here. Peter Gabriel had 4 self-titled
        # albums after all.
        albumName = part4[rand4] + " " + part5[rand5]
        albumEntry = { "artist_name" : badName, "album_name" : albumName }
        albumJson.append(albumEntry)
      print (albumJson)
      albumsCollection.insert_many(albumJson)
      
      # Creates a bar-delimited list of previously used names.
      # MongoDB expects the application to enforce data integrity rules.
      if previousNames == "":
        previousNames = badName
      else:
        previousNames = previousNames + "|" + badName
      nameCount = 1 + nameCount
    else:
      print ("Found a duplicate of [" + badName + "]")

  print (artistJson)
  artistsCollection.insert_many(artistJson)

  # Close the Connection
  client.close()
  return 0

if __name__ == "__main__":
	main(sys.argv[1:])

Listing 6 - Creating Random Data

Jeden zajímavý postřeh ohledně tohoto kódu, alespoň ve srovnání s příklady orientovanými na SQL v Python Database Programming s SQL Express pro začátečníky, je ten, že je mnohem jednodušší, protože zde není žádná další komponenta SQL. Funkce JSON jsou již součástí Pythonu a jediný příkaz související s MongoDB je insert_many() funkce, které se provádějí po vytvoření každé datové sady. Ještě pohodlnější je, že tyto příkazy odpovídají stejné syntaxi v Pythonu, která se používá v prostředí MongoDB.

Z hlediska zabezpečení problémy jako SQL Injection v takovém kódu prostě neexistují, a to nejen proto, že není prováděn žádný SQL, ale do databáze není předáván absolutně žádný kód. Funkce Python List se také stará o problémy, jako je escapování uvozovek.

Místo zobrazení výstupu v okně příkazového řádku bude k dotazování databáze místo toho použit jiný kus kódu.

Ověření vložení pomocí Pythonu

Níže uvedený kód se dotáže databáze MongoDB na akce vložení provedené výše pomocí Pythonu:

# bad-band-name-display-nosql.py

import sys
import pymongo

def main(argv):
  # Connect to the RazorDemo database.
  client = pymongo.MongoClient("mongodb+srv://yourUser:[email protected]/RazorDemo?retryWrites=true&w=majority", 
    serverSelectionTimeoutMS=5000)
  artistsCollection = client["RazorDemo"]["Artists"]
  albumsCollection = client["RazorDemo"]["Albums"]

  print ("Albums:")
  artists = artistsCollection.find()
  
  for artist in artists:
    print (str(artist["artist_name"]))
    albumQuery = { "artist_name": {"$eq" : str(artist["artist_name"])} }
    albumsForThisArtist = albumsCollection.find(albumQuery)
    for album in albumsForThisArtist:
      print ("\t" + str(album["album_name"]))

  # Close the Connection
  client.close()
  return 0

if __name__ == "__main__":
	main(sys.argv[1:])

Listing 7 - Validating the Insert Actions

Níže uvedený výstup obsahuje počáteční dokumenty vytvořené dále v dokumentu:

Obrázek 3 – Ověřování příloh

Dotazování na data MongoDB pomocí Pythonu

Výše uvedený kód lze upravit do interaktivního nástroje pro dotazování na data pomocí uživatelského vstupu. MongoDB poskytuje pro své kolekce výkonný nástroj pro textové vyhledávání, ale aby jej bylo možné povolit, musí být pro kolekce, které mají být prohledávány, vytvořeny textové indexy:

db.Artists.createIndex({artist_name: "text"})

db.Albums.createIndex({artist_name: "text", album_name: "text"})

Listing 8 - Creating Text Indices for each collection

Všimněte si, že MongoDB umožňuje pouze jeden textový index na kolekci. Pokus o vytvoření dalšího indexu pro jiný uzel v kolekci způsobí chybu. Výstup těchto příkazů v prostředí MongoDB Shell je níže:

Obrázek 4 – Přidání textových indexů

Zatímco nástroj pro vyhledávání textu může provádět všechny druhy bláznivé logiky shody zahrnující regulární výrazy a částečné shody s hodnocením podobnosti, níže uvedený příklad zůstane u jednoduchého shody, aby ilustroval důkaz konceptu:

# bad-band-name-query-nosql.py

import sys
import pymongo

def main(argv):
  searchValue = input("Enter something: ")
  # Cap the length at something reasonable. The first 20 characters.
  searchValue = searchValue[0:20]
  # Set the search value to lower case so we can perform case-insensitive matching:
  searchValue = searchValue.lower()

  # Connect to the RazorDemo database.
  client = pymongo.MongoClient("mongodb+srv://yourUser:[email protected]/RazorDemo?retryWrites=true&w=majority", 
    serverSelectionTimeoutMS=5000)
  artistsCollection = client["RazorDemo"]["Artists"]
  albumsCollection = client["RazorDemo"]["Albums"]

  matchedArtists = "";
  artists = artistsCollection.find( { "$text":{ "$search": searchValue} })

  for artist in artists:
    matchedArtists = matchedArtists + "\t" + str(artist["artist_name"]) + "\r\n"
  if "" == matchedArtists:
    print ("No matched artists.")
  else:
    print ("Matched Artists:")
    print (matchedArtists)

  
  albums = albumsCollection.find( { "$text":{ "$search": searchValue} })
  matchedAlbums = ""
  for album in albums:
    matchedAlbums = matchedAlbums + "\t" + str(album["artist_name"]) + " - " + str(album["album_name"]) + "\r\n"
    
  if "" == matchedAlbums:
    print ("No matched albums.")
  else:
    print ("Matched Albums:")
    print (matchedAlbums)
    
  # Close the Connection
  client.close()
  return 0

if __name__ == "__main__":
	main(sys.argv[1:])


Listing 9 - Querying the data

Všimněte si, že žádná konverze dat pocházejících z MongoDB nebyla nutná k tomu, aby byla přiřazena k verzi hledaného výrazu s malými písmeny.

Závěrečné úvahy o vývoji Pythonu a MongoDB

Pro vývojáře, kteří kódovali proti databázovým serverům a databázím orientovaným na SQL, může skok k noSQL připadat jako velmi strmá křivka učení, ale mapováním známých konceptů SQL databází na jejich protějšky NoSQL se stává o něco méně nepříjemným stoupáním. . Tito vývojáři mohou být dokonce šokováni nedostatkem „základních“ „funkcí“, jako je vynucení cizího klíče nebo očekávání, že se očekává, že pravidla integrity dat bude vynucovat aplikace, nikoli databáze. Velmi zkušeným vývojářům databází orientovaných na SQL připadá i pouhá myšlenka na takové nápady téměř jako programátorské kacířství!

Ale databáze NoSQL, jako je MongoDB, přidávají mnoho dalších funkcí, díky kterým se změna myšlení vyplatí. Nemusíte se starat o další verzi SQL, která je „dostatečně odlišná“, aby byla otravná, nebo nemusíte přemýšlet o problémech, jako je injekce SQL, možnost vkládat více záznamů, chyb, dokumentů dat bezpečně bez potíží „ tisíce“ jednotlivých prohlášení a možná i zábavné „Bláznivá“ myšlenka, že nechat aplikaci provádět vynucování dat oholí obrovský kus úsilí o vývoj aplikací, stojí za zvážení.


  1. Funkce Mongo Find() nevyloučí _id

  2. Třídění bez ohledu na velikost písmen v MongoDB

  3. Jaké je nejlepší grafické uživatelské rozhraní MongoDB? — Aktualizace 2019

  4. Jak udržím has_many :through vztahy při serializaci do JSON a zpět v Rails 4.0.3?