sql >> Databasteknik >  >> NoSQL >> MongoDB

Python och MongoDB databasutveckling

Som nämnts i den första delen av denna serie:Python-databasprogrammering med MongoDB, Python-modulen PyMongo krävs för att Python ska kunna kommunicera med en MongoDB-databas. För att installera detta, använd kommandot vid Windows kommandotolk:

pip3 install pymongo

Installation av PyMongo bör producera en utdata som liknar det som visas nedan:

Figur 1 – Installera PyMongo-modulen

Beroende på Python-konfigurationen, en extra modul med namnet dnspython kan också vara nödvändigt:

pip3 install dnspython

Figur 2 – Installera dnspython modul

Hur man infogar data i MongoDB med Python

Koden nedan kommer att skapa 15 slumpmässigt genererade Artister och två album för var och en av dem:

# 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

En intressant observation om denna kod, åtminstone jämfört med de SQL-orienterade exemplen i Python Database Programmering med SQL Express för nybörjare, är att det är mycket enklare, eftersom det inte finns någon extra SQL-komponent. JSON-funktionerna är redan en del av Python och det enda MongoDB-relaterade kommandot är insert_many() funktioner som exekveras efter att varje datauppsättning har skapats. Ännu bekvämare, dessa kommandon matchar samma syntax i Python som används i MongoDB-skalet.

Ur säkerhetssynpunkt existerar problem som SQL Injection helt enkelt inte i sådan kod, inte bara för att det inte finns någon SQL som exekveras, utan absolut ingen kod överhuvudtaget skickas in i databasen. Python List-funktionaliteten tar också hand om problem som att undvika citattecken.

Istället för att visa utdata i kommandotolksfönstret, kommer en annan kod att användas för att fråga databasen istället.

Validera inläggen med Python

Koden nedan kommer att fråga MongoDB-databasen efter infogningsåtgärderna ovan med Python:

# 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

Utdata nedan innehåller de första dokumenten som skapats längre upp i dokumentet:

Figur 3 – Validera inläggen

Fråga MongoDB-data med Python

Koden ovan kan anpassas till ett interaktivt verktyg för att fråga data med användarinmatning. MongoDB tillhandahåller ett kraftfullt textsökverktyg för sina samlingar, men för att aktivera det måste textindex skapas på samlingarna som ska sökas i:

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

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

Listing 8 - Creating Text Indices for each collection

Observera att MongoDB endast tillåter ett textindex per samling. Ett försök att skapa ett annat index för en annan nod i en samling kommer att orsaka ett fel. Utdata från dessa kommandon i MongoDB Shell är nedan:

Figur 4 – Lägga till textindex

Medan textsökningsverktyget kan utföra alla typer av galen matchningslogik som involverar reguljära uttryck och partiella matchningar med närhetsrankning, kommer exemplet nedan att hålla sig till enkel matchning, för att illustrera proof of concept:

# 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

Observera att ingen konvertering av data som kom från MongoDB behövdes för att matcha den med den gemena versionen av söktermen.

Sluta tankar om Python och MongoDB-utveckling

För utvecklare som har kodat mot SQL-orienterade databasservrar och databaser kan språnget till noSQL kännas som att skala en mycket brant inlärningskurva, men genom att kartlägga välbekanta SQL-databaskoncept till sina NoSQL-motsvarigheter blir det lite mindre obekvämt att klättra . Sådana utvecklare kan till och med bli chockade över avsaknaden av "grundläggande" "funktioner" såsom upprätthållande av främmande nyckel eller förväntan att det är applikationen och inte databasen som förväntas upprätthålla regler för dataintegritet. För mycket erfarna SQL-orienterade databasutvecklare känns till och med tanken på sådana idéer nästan som att programmera kätteri!

Men NoSQL-databaser som MongoDB lägger till många andra funktioner som gör förändringen i tänkandet värt det. Att inte behöva oroa sig för ännu en version av SQL som är "bara tillräckligt annorlunda" för att vara irriterande, eller inte behöva tänka på problem som SQL-injektion, att kunna infoga flera poster, fel, dokument med data säkert utan krångel med " tusentals” enskilda uttalanden, och kanske till och med underhållande den "galna" idén att låta applikationen göra datatillämpningen rakar bort en stor del av applikationsutvecklingsinsatser gör det värt att överväga.


  1. Implementera paginering med MongoDB, Express.js &Slush

  2. Hur man använder kryptering för att skydda dina MongoDB-data

  3. Meteor utan mongo

  4. Hur man summerar värdet av en nyckel över alla dokument i en MongoDB-samling