MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Разработване на база данни на Python и MongoDB

Както бе споменато в първата част на тази серия:Програмиране на база данни на Python с MongoDB, модулът на Python PyMongo е необходимо, за да може Python да комуникира с база данни MongoDB. За да инсталирате това, използвайте командата в командния ред на Windows:

pip3 install pymongo

Инсталирането на PyMongo трябва да доведе до изход, подобен на показания по-долу:

Фигура 1 – Инсталиране на модула PyMongo

В зависимост от конфигурацията на Python, допълнителен модул с име dnspython може също да е необходимо:

pip3 install dnspython

Фигура 2 – Инсталиране на dnspython модул

Как да вмъкнете данни в MongoDB с Python

Кодът по-долу ще създаде 15 произволно генерирани Изпълнители и два албума за всеки от тях:

# 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

Едно интересно наблюдение за този код, поне в сравнение с ориентираните към SQL примери в програмирането на база данни на Python със SQL Express за начинаещи е, че той е много по-прост, тъй като няма допълнителен SQL компонент. JSON функциите вече са част от Python и единствената команда, свързана с MongoDB, е insert_many() функции, които се изпълняват след създаване на всеки набор от данни. Още по-удобно, тези команди съвпадат със същия синтаксис в Python, който се използва в MongoDB Shell.

От гледна точка на сигурността, проблеми като SQL инжекцията просто не съществуват в такъв код, не само защото не се изпълнява SQL, но абсолютно никакъв код не се предава в базата данни. Функционалността на Python List също се грижи за проблеми като избягване на кавички.

Вместо да се показва изходът в прозореца на командния ред, друго парче код ще бъде използвано за запитване на базата данни.

Проверка на вложките с Python

Кодът по-долу ще поиска от базата данни MongoDB за действията за вмъкване, направени по-горе с помощта на 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

Резултатът по-долу съдържа първоначалните документи, създадени по-нагоре в документа:

Фигура 3 – Проверка на вложките

Запитване на MongoDB данни с Python

Кодът по-горе може да бъде адаптиран в интерактивен инструмент за запитване на данните с въвеждане от потребителя. MongoDB предоставя мощен инструмент за търсене на текст за своите колекции, но за да го активирате, трябва да бъдат създадени текстови индекси в колекциите, които ще бъдат търсени:

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

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

Listing 8 - Creating Text Indices for each collection

Имайте предвид, че MongoDB позволява само един текстов индекс на колекция. Опитът за създаване на друг индекс за различен възел в колекция ще доведе до грешка. Резултатът от тези команди в MongoDB Shell е по-долу:

Фигура 4 – Добавяне на текстови индекси

Докато инструментът за търсене на текст може да изпълнява всякакъв вид безумна логика на съвпадение, включваща регулярни изрази и частични съвпадения с класиране по близост, примерът по-долу ще се придържа към просто съвпадение, за да илюстрира доказателството на концепцията:

# 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

Имайте предвид, че не е било необходимо преобразуване на данните, излизащи от MongoDB, за да се съпоставят с малката версия на думата за търсене.

Окончателни мисли за разработката на Python и MongoDB

За разработчиците, които са кодирали срещу SQL-ориентирани сървъри на бази данни и бази данни, скокът към noSQL може да изглежда като мащабиране на много стръмна крива на обучение, но чрез съпоставяне на познати концепции на SQL база данни с техните NoSQL колеги, става малко по-малко неудобно изкачване . Такива разработчици може дори да бъдат шокирани от липсата на „основни“ „функции“ като прилагане на външни ключове или очакването, че се очаква приложението, а не базата данни да налага правилата за целостта на данните. За много опитни разработчици на бази данни, ориентирани към SQL, дори самата мисъл за подобни идеи изглежда почти като програмна ерес!

Но NoSQL бази данни като MongoDB добавят много други функции, които правят промяната в мисленето си заслужаваща. Не е необходимо да се тревожите за още една версия на SQL, която е „достатъчно различна“, за да бъде досадна, или да не се налага да мислите за проблеми като SQL инжектиране, възможност за вмъкване на множество записи, err, документи с данни сигурно без караницата на „ хиляди” индивидуални изявления и може би дори забавни „лудата“ идея, че налагането на прилагането на данните от приложението прави огромна част от усилията за разработка на приложения, прави всичко това да си заслужава да бъде разгледано.


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Преданият аргумент трябва да бъде единичен низ от 12 байта

  2. Агрегацията на MongoDB с $lookup включва (или проектира) само някои полета за връщане от заявка

  3. Как да променя реда на масива с MongoDB?

  4. Не може да се десериализира PyMongo ObjectId от JSON

  5. MongoDB / Meteor / Експортиране на MONGO_URL към внедрени приложения