sql >> Databáze >  >> RDS >> Mysql

Databáze Python a MySQL:Praktický úvod

MySQL je dnes jedním z nejpopulárnějších systémů pro správu databází (DBMS) na trhu. V letošním hodnocení DB-Engines se umístil na druhém místě za Oracle DBMS. Protože většina softwarových aplikací potřebuje v nějaké formě interagovat s daty, programovací jazyky jako Python poskytují nástroje pro ukládání a přístup k těmto datovým zdrojům.

Pomocí technik popsaných v tomto tutoriálu budete schopni efektivně integrovat databázi MySQL s aplikací Python. Vyvinete si malou databázi MySQL pro systém hodnocení filmů a naučíte se, jak ji dotazovat přímo z kódu Pythonu.

Na konci tohoto výukového programu budete schopni:

  • Identifikujte jedinečné vlastnosti MySQL
  • Připojte svou aplikaci do databáze MySQL
  • Požádejte databázi a načtěte požadovaná data
  • Zpracování výjimek které se vyskytují při přístupu k databázi
  • Používejte doporučené postupy při vytváření databázových aplikací

Abyste z tohoto tutoriálu vytěžili maximum, měli byste mít praktické znalosti pythonských konceptů jako for smyčky, funkce, zpracování výjimek a instalace balíčků Pythonu pomocí pip . Měli byste mít také základní znalosti o systémech správy relačních databází a SQL dotazech jako SELECT , DROP , CREATE a JOIN .

Bezplatné stažení: Získejte ukázkovou kapitolu z Python Tricks:The Book, která vám ukáže osvědčené postupy Pythonu s jednoduchými příklady, které můžete okamžitě použít k psaní krásnějšího + Pythonic kódu.


Porovnání MySQL s jinými databázemi SQL

SQL je zkratka pro Structured Query Language a je široce používaným programovacím jazykem pro správu relačních databází. Možná jste slyšeli o různých variantách DBMS založených na SQL. Mezi nejoblíbenější patří MySQL, PostgreSQL, SQLite a SQL Server. Všechny tyto databáze jsou v souladu se standardy SQL, ale s různou mírou souladu.

Být open source od svého založení v roce 1995 se MySQL rychle stalo lídrem na trhu mezi řešeními SQL. MySQL je také součástí ekosystému Oracle. Zatímco jeho základní funkce je zcela zdarma, existují i ​​​​některé placené doplňky. V současné době používají MySQL všechny velké technologické firmy, včetně Google, LinkedIn, Uber, Netflix, Twitter a další.

Kromě velké open source komunity pro podporu existuje mnoho dalších důvodů úspěchu MySQL:

  1. Snadná instalace: MySQL bylo navrženo tak, aby bylo uživatelsky přívětivé. Nastavení databáze MySQL je docela jednoduché a několik široce dostupných nástrojů třetích stran, jako je phpMyAdmin, dále zjednodušuje proces nastavení. MySQL je k dispozici pro všechny hlavní operační systémy, včetně Windows, macOS, Linux a Solaris.

  2. Rychlost: MySQL má pověst mimořádně rychlého databázového řešení. Má relativně menší půdorys a je extrémně škálovatelný z dlouhodobého hlediska.

  3. Uživatelská práva a zabezpečení: MySQL je dodáván se skriptem, který vám umožňuje nastavit úroveň zabezpečení hesel, přidělovat hesla správce a přidávat a odebírat oprávnění uživatelského účtu. Tento skript zjednodušuje proces administrace pro webhostingový portál pro správu uživatelů. Jiné DBMS, jako PostgreSQL, používají konfigurační soubory, jejichž použití je složitější.

Zatímco MySQL je známé svou rychlostí a snadností použití, s PostgreSQL můžete získat pokročilejší funkce. MySQL také není plně kompatibilní s SQL a má určitá funkční omezení, například žádnou podporu pro FULL JOIN klauzule.

Můžete také čelit problémům se současným čtením a zápisem v MySQL. Pokud má váš software mnoho uživatelů, kteří do něj zapisují data najednou, pak PostgreSQL může být vhodnější volbou.

Poznámka: Pro podrobnější srovnání MySQL a PostgreSQL v kontextu reálného světa se podívejte na Proč Uber Engineering přešel z Postgres na MySQL.

SQL Server je také velmi populární DBMS a je známý pro svou spolehlivost, efektivitu a bezpečnost. Je preferován společnostmi, zejména v bankovní doméně, které pravidelně řeší velké provozní zatížení. Je to komerční řešení a je to jeden ze systémů, které jsou nejvíce kompatibilní se službami Windows.

V roce 2010, kdy Oracle získal Sun Microsystems a MySQL, se mnozí obávali o budoucnost MySQL. V té době byl Oracle největším konkurentem MySQL. Vývojáři se obávali, že se jedná o nepřátelské převzetí od Oracle s cílem zničit MySQL.

Několik vývojářů vedených Michaelem Wideniusem, původním autorem MySQL, vytvořilo větev základny kódu MySQL a položilo základ MariaDB. Cílem bylo zabezpečit přístup k MySQL a ponechat jej navždy zdarma.

K dnešnímu dni zůstává MariaDB plně licencována GPL, takže je zcela ve veřejné doméně. Některé funkce MySQL jsou na druhou stranu dostupné pouze s placenými licencemi. MariaDB také poskytuje několik extrémně užitečných funkcí, které nejsou podporovány serverem MySQL, jako je distribuované SQL a sloupcové úložiště. Další rozdíly mezi MySQL a MariaDB naleznete na webu MariaDB.

MySQL používá velmi podobnou syntaxi jako standardní SQL. Existují však některé pozoruhodné rozdíly uvedené v oficiální dokumentaci.



Instalace MySQL Server a MySQL Connector/Python

Nyní, abyste mohli začít pracovat na tomto tutoriálu, musíte nastavit dvě věci:Server MySQL a konektor MySQL . MySQL server poskytne všechny služby potřebné pro práci s vaší databází. Jakmile je server v provozu, můžete k němu připojit svou aplikaci Python pomocí konektoru MySQL/Python.


Instalace serveru MySQL

Oficiální dokumentace podrobně popisuje doporučený způsob stažení a instalace serveru MySQL. Najdete zde pokyny pro všechny oblíbené operační systémy, včetně Windows, macOS, Solaris, Linux a mnoha dalších.

Pro Windows je nejlepším způsobem stáhnout si MySQL Installer a nechat jej, aby se postaral o celý proces. Správce instalací vám také pomůže nakonfigurovat nastavení zabezpečení serveru MySQL. Na stránce Účty a role musíte zadat heslo pro root (admin) účet a také volitelně přidat další uživatele s různými oprávněními:

I když musíte zadat přihlašovací údaje pro účet root během instalace, můžete tato nastavení upravit později.

Poznámka: Zapamatujte si jméno hostitele, uživatelské jméno a heslo, protože tyto budou později vyžadovány k navázání spojení se serverem MySQL.

Přestože pro tento tutoriál potřebujete pouze server MySQL, můžete pomocí těchto instalačních programů nastavit také další užitečné nástroje, jako je MySQL Workbench. Pokud nechcete instalovat MySQL přímo do vašeho operačního systému, pak je nasazení MySQL v Linuxu pomocí Dockeru vhodnou alternativou.



Instalace MySQL Connector/Python

Ovladač databáze je část softwaru, která umožňuje aplikaci připojit se k databázovému systému a pracovat s ním. Programovací jazyky jako Python potřebují speciální ovladač, než budou moci komunikovat s databází od konkrétního dodavatele.

Tyto ovladače jsou obvykle získávány jako moduly třetích stran. Python Database API (DB-API) definuje standardní rozhraní, které musí splňovat všechny ovladače databáze Python. Tyto podrobnosti jsou zdokumentovány v PEP 249. Všechny ovladače databáze Python, jako je sqlite3 pro SQLite, psycopg pro PostgreSQL a MySQL Connector/Python pro MySQL, dodržují tato implementační pravidla.

Poznámka: Oficiální dokumentace MySQL používá termín konektor místo řidič . Technicky jsou konektory spojeny pouze s připojením k databázi, nikoli s interakcí s ní. Tento termín se však často používá pro celý modul pro přístup k databázi obsahující konektor a řidiče.

Aby byla zachována konzistence s dokumentací, uvidíte termín konektor kdykoli je zmíněno MySQL.

Mnoho populárních programovacích jazyků má své vlastní databázové API. Java má například Java Database Connectivity (JDBC) API. Pokud potřebujete připojit Java aplikaci k databázi MySQL, musíte použít konektor MySQL JDBC, který navazuje na JDBC API.

Podobně v Pythonu musíte nainstalovat konektor Python MySQL pro interakci s databází MySQL. Mnoho balíčků se řídí standardy DB-API, ale nejoblíbenější z nich je MySQL Connector/Python. Můžete to získat pomocí pip :

$ pip install mysql-connector-python

pip nainstaluje konektor jako modul třetí strany do aktuálně aktivního virtuálního prostředí. Doporučuje se nastavit pro projekt izolované virtuální prostředí spolu se všemi závislostmi.

Chcete-li otestovat, zda byla instalace úspěšná, zadejte na terminálu Python následující příkaz:

>>>
>>> import mysql.connector

Pokud se výše uvedený kód spustí bez chyb, pak mysql.connector je nainstalován a připraven k použití. Pokud narazíte na nějaké chyby, ujistěte se, že jste ve správném virtuálním prostředí a že používáte správný interpret Pythonu.

Ujistěte se, že instalujete správný mysql-connector-python balíček, což je implementace čistého Pythonu. Dejte si pozor na podobně pojmenované, ale dnes již odepsané konektory, jako je mysql-connector .




Navázání spojení se serverem MySQL

MySQL je serverový Systém pro správu databází. Jeden server může obsahovat více databází. Chcete-li komunikovat s databází, musíte nejprve navázat spojení se serverem. Obecný pracovní postup programu Python, který komunikuje s databází založenou na MySQL, je následující:

  1. Připojte se k serveru MySQL.
  2. Vytvořte novou databázi.
  3. Připojte se k nově vytvořené nebo existující databázi.
  4. Proveďte dotaz SQL a načtěte výsledky.
  5. Informujte databázi, pokud byly v tabulce provedeny nějaké změny.
  6. Uzavřete připojení k serveru MySQL.

Toto je obecný pracovní postup, který se může lišit v závislosti na jednotlivé aplikaci. Ale ať už se jedná o jakoukoli aplikaci, prvním krokem je propojení databáze s vaší aplikací.


Navázání připojení

Prvním krokem při interakci se serverem MySQL je navázání spojení. K tomu potřebujete connect() z mysql.connector modul. Tato funkce přebírá parametry jako host , user a password a vrátí MySQLConnection objekt. Tyto přihlašovací údaje můžete obdržet jako vstup od uživatele a předat je connect() :

from getpass import getpass
from mysql.connector import connect, Error

try:
    with connect(
        host="localhost",
        user=input("Enter username: "),
        password=getpass("Enter password: "),
    ) as connection:
        print(connection)
except Error as e:
    print(e)

Výše uvedený kód používá zadané přihlašovací údaje k navázání spojení s vaším serverem MySQL. Na oplátku získáte MySQLConnection objekt, který je uložen v connection variabilní. Od této chvíle budete tuto proměnnou používat pro přístup k serveru MySQL.

Ve výše uvedeném kódu je třeba si všimnout několika důležitých věcí:

  • Vždy byste se měli vypořádat s výjimkami, které mohou být vyvolány při navazování připojení k serveru MySQL. To je důvod, proč používáte tryexcept blok pro zachycení a tisk všech výjimek, se kterými se můžete setkat.

  • Po dokončení přístupu k databázi byste měli připojení vždy ukončit. Ponechání nepoužívaných otevřených připojení může vést k několika neočekávaným chybám a problémům s výkonem. Výše uvedený kód využívá kontextového manažera pomocí with , který abstrahuje proces čištění připojení.

  • Neměli byste nikdy nekódovat své přihlašovací údaje napevno , tedy vaše uživatelské jméno a heslo, přímo ve skriptu Python. Toto je špatný postup pro nasazení a představuje vážnou bezpečnostní hrozbu. Výše uvedený kód vyzve uživatele k zadání přihlašovacích údajů. Používá vestavěný getpass modul pro skrytí hesla. I když je to lepší než pevné kódování, existují jiné, bezpečnější způsoby ukládání citlivých informací, jako je použití proměnných prostředí.

Nyní jste vytvořili spojení mezi vaším programem a serverem MySQL, ale stále musíte buď vytvořit novou databázi, nebo se připojit k existující databázi na serveru.



Vytvoření nové databáze

V poslední části jste navázali spojení se serverem MySQL. Chcete-li vytvořit novou databázi, musíte provést příkaz SQL:

CREATE DATABASE books_db;

Výše uvedený příkaz vytvoří novou databázi s názvem books_db .

Poznámka: V MySQL je povinné vložit středník (; ) na konci příkazu, který označuje ukončení dotazu. MySQL Connector/Python však automaticky připojuje středník na konec vašich dotazů, takže jej není potřeba používat v kódu Pythonu.

Chcete-li provést SQL dotaz v Pythonu, budete muset použít kurzor, který abstrahuje přístup k databázovým záznamům. MySQL Connector/Python vám poskytuje MySQLCursor třída, která vytváří instance objektů, které mohou provádět dotazy MySQL v Pythonu. Instance MySQLCursor třída se také nazývá cursor .

cursor objekty využívají MySQLConnection objekt pro interakci s vaším serverem MySQL. Chcete-li vytvořit cursor , použijte .cursor() způsob vašeho connection proměnná:

cursor = connection.cursor()

Výše uvedený kód vám poskytuje instanci MySQLCursor třída.

Dotaz, který je třeba provést, je odeslán do cursor.execute() ve formátu řetězce. V této konkrétní příležitosti odešlete CREATE DATABASE dotaz na cursor.execute() :

from getpass import getpass
from mysql.connector import connect, Error

try:
    with connect(
        host="localhost",
        user=input("Enter username: "),
        password=getpass("Enter password: "),
    ) as connection:
        create_db_query = "CREATE DATABASE online_movie_rating"
        with connection.cursor() as cursor:
            cursor.execute(create_db_query)
except Error as e:
    print(e)

Po provedení výše uvedeného kódu budete mít novou databázi s názvem online_movie_rating na vašem serveru MySQL.

CREATE DATABASE dotaz je uložen jako řetězec v create_db_query a poté předán do cursor.execute() k provedení. Kód používá kontextového manažera s cursor objekt pro zpracování procesu čištění.

Pokud na vašem serveru již existuje databáze se stejným názvem, může se zde zobrazit chyba. Chcete-li to potvrdit, můžete zobrazit názvy všech databází na vašem serveru. Pomocí stejného MySQLConnection objekt z dřívějšího, spusťte SHOW DATABASES prohlášení:

>>>
>>> show_db_query = "SHOW DATABASES"
>>> with connection.cursor() as cursor:
...     cursor.execute(show_db_query)
...     for db in cursor:
...         print(db)
...
('information_schema',)
('mysql',)
('online_movie_rating',)
('performance_schema',)
('sys',)

Výše uvedený kód vytiskne názvy všech databází aktuálně na vašem serveru MySQL. SHOW DATABASES příkaz také vypíše některé databáze, které jste nevytvořili na svém serveru, například information_schema , performance_schema , a tak dále. Tyto databáze jsou generovány automaticky serverem MySQL a poskytují přístup k řadě databázových metadat a nastavení serveru MySQL.

V této sekci jste vytvořili novou databázi spuštěním příkazu CREATE DATABASE prohlášení. V další části uvidíte, jak se připojit k databázi, která již existuje.



Připojení k existující databázi

V poslední části jste vytvořili novou databázi s názvem online_movie_rating . Stále jste se k němu však nepřipojili. V mnoha situacích již máte databázi MySQL, kterou chcete propojit se svou aplikací Python.

Můžete to udělat pomocí stejného connect() funkci, kterou jste použili dříve, odesláním dalšího parametru s názvem database :

from getpass import getpass
from mysql.connector import connect, Error

try:
    with connect(
        host="localhost",
        user=input("Enter username: "),
        password=getpass("Enter password: "),
        database="online_movie_rating",
    ) as connection:
        print(connection)
except Error as e:
    print(e)

Výše uvedený kód je velmi podobný připojovacímu skriptu, který jste použili dříve. Jedinou změnou je zde další database parametr, kde je název vaší databáze předán do connect() . Jakmile tento skript spustíte, budete připojeni k online_movie_rating databáze.




Vytvoření, změna a vypuštění tabulky

V této části se dozvíte, jak provádět některé základní DDL dotazy, jako je CREATE , DROP a ALTER s Pythonem. Získáte rychlý pohled na databázi MySQL, kterou budete používat ve zbytku tohoto kurzu. Vytvoříte také všechny tabulky požadované pro databázi a později se naučíte, jak v těchto tabulkách provádět úpravy.


Definování schématu databáze

Můžete začít vytvořením databázového schématu pro online systém hodnocení filmů. Databáze se bude skládat ze tří tabulek:

  1. movies obsahuje obecné informace o filmech a má následující atributy:
    • id
    • title
    • release_year
    • genre
    • collection_in_mil
  2. reviewers obsahuje informace o lidech, kteří zveřejnili recenze nebo hodnocení, a má následující atributy:
    • id
    • first_name
    • last_name
  3. ratings obsahuje informace o hodnoceních, která byla zveřejněna, a má následující atributy:
    • movie_id (cizí klíč)
    • reviewer_id (cizí klíč)
    • ratings

Systém hodnocení filmů v reálném světě, jako je IMDb, by musel ukládat spoustu dalších atributů, jako jsou e-maily, seznamy filmových herců a tak dále. Pokud chcete, můžete do této databáze přidat další tabulky a atributy. Ale tyto tři tabulky budou pro účely tohoto tutoriálu stačit.

Obrázek níže znázorňuje schéma databáze:

Tabulky v této databázi spolu souvisí. movies a reviewers bude mít many-to-many vztah, protože jeden film může recenzovat více recenzentů a jeden recenzent může recenzovat více filmů. ratings tabulka spojuje movies tabulka s reviewers tabulka.



Vytváření tabulek pomocí CREATE TABLE Prohlášení

Nyní, abyste vytvořili novou tabulku v MySQL, musíte použít CREATE TABLE prohlášení. Následující dotaz MySQL vytvoří movies tabulku pro vaše online_movie_rating databáze:

CREATE TABLE movies(
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(100),
    release_year YEAR(4),
    genre VARCHAR(100),
    collection_in_mil INT
);

Pokud jste se dříve podívali na příkazy SQL, pak by většina z výše uvedených dotazů mohla dávat smysl. Ale existují určité rozdíly v syntaxi MySQL, kterých byste si měli být vědomi.

Například MySQL má širokou škálu datových typů pro vaše prohlížení, včetně YEAR , INT , BIGINT , a tak dále. MySQL také používá AUTO_INCREMENT klíčové slovo, když hodnota sloupce musí být automaticky zvýšena při vkládání nových záznamů.

Chcete-li vytvořit novou tabulku, musíte tento dotaz předat funkci cursor.execute() , který přijme dotaz MySQL a provede dotaz na připojené databázi MySQL:

create_movies_table_query = """
CREATE TABLE movies(
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(100),
    release_year YEAR(4),
    genre VARCHAR(100),
    collection_in_mil INT
)
"""
with connection.cursor() as cursor:
    cursor.execute(create_movies_table_query)
    connection.commit()

Nyní máte movies tabulky ve vaší databázi. Předáte create_movies_table_query na cursor.execute() , který provede požadované provedení.

Poznámka: connection proměnná odkazuje na MySQLConnection objekt, který byl vrácen, když jste se připojili k vaší databázi.

Všimněte si také connection.commit() prohlášení na konci kódu. Ve výchozím nastavení váš konektor MySQL nepotvrzuje transakce automaticky. V MySQL dochází k úpravám zmíněným v transakci pouze při použití COMMIT příkaz na závěr. Tuto metodu volejte vždy po každé transakci, abyste provedli změny ve skutečné tabulce.

Stejně jako u movies tabulky, spusťte následující skript a vytvořte reviewers tabulka:

create_reviewers_table_query = """
CREATE TABLE reviewers (
    id INT AUTO_INCREMENT PRIMARY KEY,
    first_name VARCHAR(100),
    last_name VARCHAR(100)
)
"""
with connection.cursor() as cursor:
    cursor.execute(create_reviewers_table_query)
    connection.commit()

V případě potřeby můžete přidat další informace o recenzentovi, jako je jeho e-mailové ID nebo demografické údaje. Ale first_name a last_name zatím poslouží vašemu účelu.

Nakonec můžete vytvořit ratings tabulky pomocí následujícího skriptu:

create_ratings_table_query = """
CREATE TABLE ratings (
    movie_id INT,
    reviewer_id INT,
    rating DECIMAL(2,1),
    FOREIGN KEY(movie_id) REFERENCES movies(id),
    FOREIGN KEY(reviewer_id) REFERENCES reviewers(id),
    PRIMARY KEY(movie_id, reviewer_id)
)
"""
with connection.cursor() as cursor:
    cursor.execute(create_ratings_table_query)
    connection.commit()

Implementace vztahů cizího klíče v MySQL je mírně odlišná a omezená ve srovnání se standardním SQL. V MySQL musí rodič i podřízený prvek v omezení cizího klíče používat stejný úložný modul .

Úložný modul je základní softwarová komponenta, kterou systém správy databází používá k provádění operací SQL. V MySQL se úložné stroje dodávají ve dvou různých variantách:

  1. Transakční úložiště jsou transakce bezpečné a umožňují vrátit transakce zpět pomocí jednoduchých příkazů jako rollback . Do této kategorie patří mnoho oblíbených enginů MySQL, včetně InnoDB a NDB.

  2. Netransakční moduly úložiště závisí na propracovaném ručním kódu pro vrácení příkazů provedených v databázi. MyISAM, MEMORY a mnoho dalších enginů MySQL jsou netransakční.

InnoDB je výchozí a nejoblíbenější úložiště. Pomáhá udržovat integritu dat podporou omezení cizích klíčů. To znamená, že jakákoli operace CRUD na cizím klíči je zkontrolována, aby se zajistilo, že nepovede k nekonzistentnosti v různých tabulkách.

Všimněte si také, že ratings tabulka používá sloupce movie_id a reviewer_id , oba cizí klíče, společně jako primární klíč . Tento krok zajišťuje, že recenzent nemůže ohodnotit stejný film dvakrát.

Můžete se rozhodnout znovu použít stejný kurzor pro více spuštění. V takovém případě by se všechna provedení stala jednou atomickou transakcí spíše než několika samostatnými transakcemi. Můžete například spustit všechny CREATE TABLE příkazy s jedním kurzorem a poté transakci potvrďte pouze jednou:

with connection.cursor() as cursor:
    cursor.execute(create_movies_table_query)
    cursor.execute(create_reviewers_table_query)
    cursor.execute(create_ratings_table_query)
    connection.commit()

Výše uvedený kód nejprve provede všechny tři CREATE prohlášení. Poté odešle COMMIT příkaz k serveru MySQL, který potvrdí vaši transakci. Můžete také použít .rollback() odeslat ROLLBACK příkaz na server MySQL a odstraňte všechny změny dat z transakce.



Zobrazení schématu tabulky pomocí DESCRIBE Prohlášení

Nyní, když jste vytvořili všechny tři tabulky, můžete se podívat na jejich schéma pomocí následujícího příkazu SQL:

DESCRIBE <table_name>;

Chcete-li získat zpět některé výsledky z cursor objekt, musíte použít cursor.fetchall() . Tato metoda načte všechny řádky z posledního provedeného příkazu. Za předpokladu, že již máte MySQLConnection objekt v connection proměnnou, můžete vytisknout všechny výsledky načtené pomocí cursor.fetchall() :

>>>
>>> show_table_query = "DESCRIBE movies"
>>> with connection.cursor() as cursor:
...     cursor.execute(show_table_query)
...     # Fetch rows from last executed query
...     result = cursor.fetchall()
...     for row in result:
...         print(row)
...
('id', 'int(11)', 'NO', 'PRI', None, 'auto_increment')
('title', 'varchar(100)', 'YES', '', None, '')
('release_year', 'year(4)', 'YES', '', None, '')
('genre', 'varchar(100)', 'YES', '', None, '')
('collection_in_mil', 'int(11)', 'YES', '', None, '')

Po provedení výše uvedeného kódu byste měli obdržet tabulku obsahující informace o všech sloupcích v movies stůl. Pro každý sloupec obdržíte podrobnosti, jako je typ dat sloupce, zda je sloupec primárním klíčem atd.



Úprava schématu tabulky pomocí ALTER Prohlášení

V movies tabulka, máte sloupec nazvaný collection_in_mil , která obsahuje sbírku filmových pokladen v milionech dolarů. Chcete-li upravit datový typ collection_in_mil, můžete napsat následující příkaz MySQL atribut z INT na DECIMAL :

ALTER TABLE movies MODIFY COLUMN collection_in_mil DECIMAL(4,1);

DECIMAL(4,1) znamená desetinné číslo, které může mít maximálně 4 číslic, z toho 1 je desítkové, například 120.1 , 3.4 , 38.0 , a tak dále. Po provedení ALTER TABLE můžete zobrazit aktualizované schéma tabulky pomocí DESCRIBE :

>>>
>>> alter_table_query = """
... ALTER TABLE movies
... MODIFY COLUMN collection_in_mil DECIMAL(4,1)
... """
>>> show_table_query = "DESCRIBE movies"
>>> with connection.cursor() as cursor:
...     cursor.execute(alter_table_query)
...     cursor.execute(show_table_query)
...     # Fetch rows from last executed query
...     result = cursor.fetchall()
...     print("Movie Table Schema after alteration:")
...     for row in result:
...         print(row)
...
Movie Table Schema after alteration
('id', 'int(11)', 'NO', 'PRI', None, 'auto_increment')
('title', 'varchar(100)', 'YES', '', None, '')
('release_year', 'year(4)', 'YES', '', None, '')
('genre', 'varchar(100)', 'YES', '', None, '')
('collection_in_mil', 'decimal(4,1)', 'YES', '', None, '')

Jak je znázorněno na výstupu, collection_in_mil atribut je nyní typu DECIMAL(4,1) . Všimněte si také, že ve výše uvedeném kódu voláte cursor.execute() dvakrát. Ale cursor.fetchall() načte řádky pouze z posledního provedeného dotazu, což je show_table_query .



Mazání tabulek pomocí DROP Prohlášení

Chcete-li odstranit tabulku, musíte provést DROP TABLE příkaz v MySQL. Smazání tabulky je nevratné proces. Pokud spustíte kód níže, budete muset zavolat CREATE TABLE dotaz znovu a použijte ratings tabulka v nadcházejících sekcích.

Chcete-li odstranit ratings tabulky, odešlete drop_table_query na cursor.execute() :

drop_table_query = "DROP TABLE ratings"
with connection.cursor() as cursor:
    cursor.execute(drop_table_query)

Pokud provedete výše uvedený kód, úspěšně smažete ratings tabulka.




Vkládání záznamů do tabulek

V poslední části jste v databázi vytvořili tři tabulky:movies , reviewers a ratings . Nyní musíte tyto tabulky naplnit daty. Tato část se bude zabývat dvěma různými způsoby vkládání záznamů do konektoru MySQL pro Python.

První metoda, .execute() , funguje dobře, když je počet záznamů malý a záznamy lze pevně zakódovat. Druhá metoda, .executemany() , je populárnější a lépe se hodí pro scénáře reálného světa.


Pomocí .execute()

První přístup používá stejný cursor.execute() metodu, kterou jste dosud používali. Napište INSERT INTO dotaz v řetězci a předejte jej cursor.execute() . Tuto metodu můžete použít k vložení dat do movies tabulka.

Pro informaci, movies tabulka má pět atributů:

  1. id
  2. title
  3. release_year
  4. genre
  5. collection_in_mil

Nemusíte přidávat data pro id jako AUTO_INCREMENT automaticky vypočítá id pro tebe. Následující skript vloží záznamy do movies tabulka:

insert_movies_query = """
INSERT INTO movies (title, release_year, genre, collection_in_mil)
VALUES
    ("Forrest Gump", 1994, "Drama", 330.2),
    ("3 Idiots", 2009, "Drama", 2.4),
    ("Eternal Sunshine of the Spotless Mind", 2004, "Drama", 34.5),
    ("Good Will Hunting", 1997, "Drama", 138.1),
    ("Skyfall", 2012, "Action", 304.6),
    ("Gladiator", 2000, "Action", 188.7),
    ("Black", 2005, "Drama", 3.0),
    ("Titanic", 1997, "Romance", 659.2),
    ("The Shawshank Redemption", 1994, "Drama",28.4),
    ("Udaan", 2010, "Drama", 1.5),
    ("Home Alone", 1990, "Comedy", 286.9),
    ("Casablanca", 1942, "Romance", 1.0),
    ("Avengers: Endgame", 2019, "Action", 858.8),
    ("Night of the Living Dead", 1968, "Horror", 2.5),
    ("The Godfather", 1972, "Crime", 135.6),
    ("Haider", 2014, "Action", 4.2),
    ("Inception", 2010, "Adventure", 293.7),
    ("Evil", 2003, "Horror", 1.3),
    ("Toy Story 4", 2019, "Animation", 434.9),
    ("Air Force One", 1997, "Drama", 138.1),
    ("The Dark Knight", 2008, "Action",535.4),
    ("Bhaag Milkha Bhaag", 2013, "Sport", 4.1),
    ("The Lion King", 1994, "Animation", 423.6),
    ("Pulp Fiction", 1994, "Crime", 108.8),
    ("Kai Po Che", 2013, "Sport", 6.0),
    ("Beasts of No Nation", 2015, "War", 1.4),
    ("Andadhun", 2018, "Thriller", 2.9),
    ("The Silence of the Lambs", 1991, "Crime", 68.2),
    ("Deadpool", 2016, "Action", 363.6),
    ("Drishyam", 2015, "Mystery", 3.0)
"""
with connection.cursor() as cursor:
    cursor.execute(insert_movies_query)
    connection.commit()

The movies table is now loaded with thirty records. The code calls connection.commit() at the end. It’s crucial to call .commit() after preforming any modifications to a table.



Using .executemany()

The previous approach is more suitable when the number of records is fairly small and you can write these records directly into the code. But this is rarely true. You’ll often have this data stored in some other file, or the data will be generated by a different script and will need to be added to the MySQL database.

This is where .executemany() comes in handy. It accepts two parameters:

  1. A query that contains placeholders for the records that need to be inserted
  2. A list that contains all records that you wish to insert

The following example inserts records for the reviewers table:

insert_reviewers_query = """
INSERT INTO reviewers
(first_name, last_name)
VALUES ( %s, %s )
"""
reviewers_records = [
    ("Chaitanya", "Baweja"),
    ("Mary", "Cooper"),
    ("John", "Wayne"),
    ("Thomas", "Stoneman"),
    ("Penny", "Hofstadter"),
    ("Mitchell", "Marsh"),
    ("Wyatt", "Skaggs"),
    ("Andre", "Veiga"),
    ("Sheldon", "Cooper"),
    ("Kimbra", "Masters"),
    ("Kat", "Dennings"),
    ("Bruce", "Wayne"),
    ("Domingo", "Cortes"),
    ("Rajesh", "Koothrappali"),
    ("Ben", "Glocker"),
    ("Mahinder", "Dhoni"),
    ("Akbar", "Khan"),
    ("Howard", "Wolowitz"),
    ("Pinkie", "Petit"),
    ("Gurkaran", "Singh"),
    ("Amy", "Farah Fowler"),
    ("Marlon", "Crafford"),
]
with connection.cursor() as cursor:
    cursor.executemany(insert_reviewers_query, reviewers_records)
    connection.commit()

In the script above, you pass both the query and the list of records as arguments to .executemany() . These records could have been fetched from a file or from the user and stored in the reviewers_records list.

The code uses %s as a placeholder for the two strings that had to be inserted in the insert_reviewers_query . Placeholders act as format specifiers and help reserve a spot for a variable inside a string. The specified variable is then added to this spot during execution.

You can similarly use .executemany() to insert records in the ratings table:

insert_ratings_query = """
INSERT INTO ratings
(rating, movie_id, reviewer_id)
VALUES ( %s, %s, %s)
"""
ratings_records = [
    (6.4, 17, 5), (5.6, 19, 1), (6.3, 22, 14), (5.1, 21, 17),
    (5.0, 5, 5), (6.5, 21, 5), (8.5, 30, 13), (9.7, 6, 4),
    (8.5, 24, 12), (9.9, 14, 9), (8.7, 26, 14), (9.9, 6, 10),
    (5.1, 30, 6), (5.4, 18, 16), (6.2, 6, 20), (7.3, 21, 19),
    (8.1, 17, 18), (5.0, 7, 2), (9.8, 23, 3), (8.0, 22, 9),
    (8.5, 11, 13), (5.0, 5, 11), (5.7, 8, 2), (7.6, 25, 19),
    (5.2, 18, 15), (9.7, 13, 3), (5.8, 18, 8), (5.8, 30, 15),
    (8.4, 21, 18), (6.2, 23, 16), (7.0, 10, 18), (9.5, 30, 20),
    (8.9, 3, 19), (6.4, 12, 2), (7.8, 12, 22), (9.9, 15, 13),
    (7.5, 20, 17), (9.0, 25, 6), (8.5, 23, 2), (5.3, 30, 17),
    (6.4, 5, 10), (8.1, 5, 21), (5.7, 22, 1), (6.3, 28, 4),
    (9.8, 13, 1)
]
with connection.cursor() as cursor:
    cursor.executemany(insert_ratings_query, ratings_records)
    connection.commit()

All three tables are now populated with data. You now have a fully functional online movie rating database. The next step is to understand how to interact with this database.




Reading Records From the Database

Until now, you’ve been building your database. Now it’s time to perform some queries on it and find some interesting properties from this dataset. In this section, you’ll learn how to read records from database tables using the SELECT statement.


Reading Records Using the SELECT Statement

To retrieve records, you need to send a SELECT query to cursor.execute() . Then you use cursor.fetchall() to extract the retrieved table in the form of a list of rows or records.

Try writing a MySQL query to select all records from the movies table and send it to .execute() :

>>>
>>> select_movies_query = "SELECT * FROM movies LIMIT 5"
>>> with connection.cursor() as cursor:
...     cursor.execute(select_movies_query)
...     result = cursor.fetchall()
...     for row in result:
...         print(row)
...
(1, 'Forrest Gump', 1994, 'Drama', Decimal('330.2'))
(2, '3 Idiots', 2009, 'Drama', Decimal('2.4'))
(3, 'Eternal Sunshine of the Spotless Mind', 2004, 'Drama', Decimal('34.5'))
(4, 'Good Will Hunting', 1997, 'Drama', Decimal('138.1'))
(5, 'Skyfall', 2012, 'Action', Decimal('304.6'))

The result variable holds the records returned from using .fetchall() . It’s a list of tuples representing individual records from the table.

In the query above, you use the LIMIT clause to constrain the number of rows that are received from the SELECT prohlášení. Developers often use LIMIT to perform pagination when handling large volumes of data.

In MySQL, the LIMIT clause takes one or two nonnegative numeric arguments. When using one argument, you specify the maximum number of rows to return. Since your query includes LIMIT 5 , only the first 5 records are fetched. When using both arguments, you can also specify the offset of the first row to return:

SELECT * FROM movies LIMIT 2,5;

The first argument specifies an offset of 2 , and the second argument constrains the number of returned rows to 5 . The above query will return rows 3 to 7.

You can also query for selected columns:

>>>
>>> select_movies_query = "SELECT title, release_year FROM movies LIMIT 5"
>>> with connection.cursor() as cursor:
...     cursor.execute(select_movies_query)
...     for row in cursor.fetchall():
...         print(row)
...
('Forrest Gump', 1994)
('3 Idiots', 2009)
('Eternal Sunshine of the Spotless Mind', 2004)
('Good Will Hunting', 1997)
('Skyfall', 2012)

Now, the code outputs values only from the two specified columns:title and release_year .



Filtering Results Using the WHERE Clause

You can filter table records by specific criteria using the WHERE clause. For example, to retrieve all movies with a box office collection greater than $300 million, you could run the following query:

SELECT title, collection_in_mil
FROM movies
WHERE collection_in_mil > 300;

You can also use ORDER BY clause in the last query to sort the results from the highest to the lowest earner:

>>>
>>> select_movies_query = """
... SELECT title, collection_in_mil
... FROM movies
... WHERE collection_in_mil > 300
... ORDER BY collection_in_mil DESC
... """
>>> with connection.cursor() as cursor:
...     cursor.execute(select_movies_query)
...     for movie in cursor.fetchall():
...         print(movie)
...
('Avengers: Endgame', Decimal('858.8'))
('Titanic', Decimal('659.2'))
('The Dark Knight', Decimal('535.4'))
('Toy Story 4', Decimal('434.9'))
('The Lion King', Decimal('423.6'))
('Deadpool', Decimal('363.6'))
('Forrest Gump', Decimal('330.2'))
('Skyfall', Decimal('304.6'))

MySQL offers a plethora of string formatting operations like CONCAT for concatenating strings. Often, websites will show the movie title along with its release year to avoid confusion. To retrieve the titles of the top five grossing movies, concatenated with their release years, you can write the following query:

>>>
>>> select_movies_query = """
... SELECT CONCAT(title, " (", release_year, ")"),
...       collection_in_mil
... FROM movies
... ORDER BY collection_in_mil DESC
... LIMIT 5
... """
>>> with connection.cursor() as cursor:
...     cursor.execute(select_movies_query)
...     for movie in cursor.fetchall():
...         print(movie)
...
('Avengers: Endgame (2019)', Decimal('858.8'))
('Titanic (1997)', Decimal('659.2'))
('The Dark Knight (2008)', Decimal('535.4'))
('Toy Story 4 (2019)', Decimal('434.9'))
('The Lion King (1994)', Decimal('423.6'))

If you don’t want to use the LIMIT clause and you don’t need to fetch all the records, then the cursor object has .fetchone() and .fetchmany() methods as well:

  • .fetchone() retrieves either the next row of the result, as a tuple, or None if no more rows are available.
  • .fetchmany() retrieves the next set of rows from the result as a list of tuples. It has a size argument, which defaults to 1 , that you can use to specify the number of rows you need to fetch. If no more rows are available, then the method returns an empty list.

Try retrieving the titles of the five highest-grossing movies concatenated with their release years again, but this time use .fetchmany() :

>>>
>>> select_movies_query = """
... SELECT CONCAT(title, " (", release_year, ")"),
...       collection_in_mil
... FROM movies
... ORDER BY collection_in_mil DESC
... """
>>> with connection.cursor() as cursor:
...     cursor.execute(select_movies_query)
...     for movie in cursor.fetchmany(size=5):
...         print(movie)
...     cursor.fetchall()
...
('Avengers: Endgame (2019)', Decimal('858.8'))
('Titanic (1997)', Decimal('659.2'))
('The Dark Knight (2008)', Decimal('535.4'))
('Toy Story 4 (2019)', Decimal('434.9'))
('The Lion King (1994)', Decimal('423.6'))

The output with .fetchmany() is similar to what you received when you used the LIMIT clause. You might have noticed the additional cursor.fetchall() call at the end. You do this to clean all the remaining results that weren’t read by .fetchmany() .

It’s necessary to clean all unread results before executing any other statements on the same connection. Otherwise, an InternalError: Unread result found exception will be raised.




Handling Multiple Tables Using the JOIN Statement

If you found the queries in the last section to be quite straightforward, don’t worry. You can make your SELECT queries as complex as you want using the same methods from the last section.

Let’s look at some slightly more complex JOIN queries. If you want to find out the name of the top five highest-rated movies in your database, then you can run the following query:

>>>
>>> select_movies_query = """
... SELECT title, AVG(rating) as average_rating
... FROM ratings
... INNER JOIN movies
...     ON movies.id = ratings.movie_id
... GROUP BY movie_id
... ORDER BY average_rating DESC
... LIMIT 5
... """
>>> with connection.cursor() as cursor:
...     cursor.execute(select_movies_query)
...     for movie in cursor.fetchall():
...         print(movie)
...
('Night of the Living Dead', Decimal('9.90000'))
('The Godfather', Decimal('9.90000'))
('Avengers: Endgame', Decimal('9.75000'))
('Eternal Sunshine of the Spotless Mind', Decimal('8.90000'))
('Beasts of No Nation', Decimal('8.70000'))

As shown above, Night of the Living Dead and The Godfather are tied as the highest-rated movies in your online_movie_rating database.

To find the name of the reviewer who gave the most ratings, write the following query:

>>>
>>> select_movies_query = """
... SELECT CONCAT(first_name, " ", last_name), COUNT(*) as num
... FROM reviewers
... INNER JOIN ratings
...     ON reviewers.id = ratings.reviewer_id
... GROUP BY reviewer_id
... ORDER BY num DESC
... LIMIT 1
... """
>>> with connection.cursor() as cursor:
...     cursor.execute(select_movies_query)
...     for movie in cursor.fetchall():
...         print(movie)
...
('Mary Cooper', 4)

Mary Cooper is the most frequent reviewer in this database. As seen above, it doesn’t matter how complicated the query is because it’s ultimately handled by the MySQL server. Your process for executing a query will always remain the same:pass the query to cursor.execute() and fetch the results using .fetchall() .



Updating and Deleting Records From the Database

In this section, you’ll be updating and deleting records from the database. Both of these operations can be performed on either a single record or multiple records in the table. You’ll select the rows that need to be modified using the WHERE clause.


UPDATE Command

One of the reviewers in your database, Amy Farah Fowler , is now married to Sheldon Cooper . Her last name has now changed to Cooper , so you need to update your database accordingly. For updating records, MySQL uses the UPDATE statement:

update_query = """
UPDATE
    reviewers
SET
    last_name = "Cooper"
WHERE
    first_name = "Amy"
"""
with connection.cursor() as cursor:
    cursor.execute(update_query)
    connection.commit()

The code passes the update query to cursor.execute() , and .commit() brings the required changes to the reviewers table.

Note: In the UPDATE query, the WHERE clause helps specify the records that need to be updated. If you don’t use WHERE , then all records will be updated!

Suppose you need to provide an option that allows reviewers to modify ratings. A reviewer will provide three values, movie_id , reviewer_id , and the new rating . The code will display the record after performing the specified modification.

Assuming that movie_id = 18 , reviewer_id = 15 , and the new rating = 5.0 , you can use the following MySQL queries to perform the required modification:

UPDATE
    ratings
SET
    rating = 5.0
WHERE
    movie_id = 18 AND reviewer_id = 15;

SELECT *
FROM ratings
WHERE
    movie_id = 18 AND reviewer_id = 15;

The above queries first update the rating and then display it. You can create a complete Python script that establises a connection with the database and allows the reviewer to modify a rating:

from getpass import getpass
from mysql.connector import connect, Error

movie_id = input("Enter movie id: ")
reviewer_id = input("Enter reviewer id: ")
new_rating = input("Enter new rating: ")
update_query = """
UPDATE
    ratings
SET
    rating = "%s"
WHERE
    movie_id = "%s" AND reviewer_id = "%s";

SELECT *
FROM ratings
WHERE
    movie_id = "%s" AND reviewer_id = "%s"
""" % (
    new_rating,
    movie_id,
    reviewer_id,
    movie_id,
    reviewer_id,
)

try:
    with connect(
        host="localhost",
        user=input("Enter username: "),
        password=getpass("Enter password: "),
        database="online_movie_rating",
    ) as connection:
        with connection.cursor() as cursor:
            for result in cursor.execute(update_query, multi=True):
                if result.with_rows:
                    print(result.fetchall())
            connection.commit()
except Error as e:
    print(e)

Save this code to a file named modify_ratings.py . The above code uses %s placeholders to insert the received input in the update_query tětiva. For the first time in this tutorial, you have multiple queries inside a single string. To pass multiple queries to a single cursor.execute() , you need to set the method’s multi argument to True .

If multi is True , then cursor.execute() returns an iterator. Each item in the iterator corresponds to a cursor object that executes a statement passed in the query. The above code runs a for loop on this iterator and then calls .fetchall() on each cursor object.

Note: Running .fetchall() on all cursor objects is important. To execute a new statement on the same connection, you must ensure that there are no unread results from previous executions. If there are unread results, then you’ll receive an exception.

If no result set is fetched on an operation, then .fetchall() raises an exception. To avoid this error, in the code above you use the cursor.with_rows property, which indicates whether the most recently executed operation produced rows.

While this code should solve your purpose, the WHERE clause is a prime target for web hackers in its current state. It’s vulnerable to what is called a SQL injection attack, which can allow malicious actors to either corrupt or misuse your database.

Warning :Don’t try the below inputs on your database! They will corrupt your table and you’ll need to recreate it.

For example, if a user sends movie_id=18 , reviewer_id=15 , and the new rating=5.0 as input, then the output looks like this:

$ python modify_ratings.py
Enter movie id: 18
Enter reviewer id: 15
Enter new rating: 5.0
Enter username: <user_name>
Enter password:
[(18, 15, Decimal('5.0'))]

The rating with movie_id=18 and reviewer_id=15 has been changed to 5.0 . But if you were hacker, then you might send a hidden command in your input:

$ python modify_ratings.py
Enter movie id: 18
Enter reviewer id: 15"; UPDATE reviewers SET last_name = "A
Enter new rating: 5.0
Enter username: <user_name>
Enter password:
[(18, 15, Decimal('5.0'))]

Again, the output shows that the specified rating has been changed to 5.0 . What’s changed?

The hacker sneaked in an update query while entering the reviewer_id . The update query, update reviewers set last_name = "A , changes the last_name of all records in the reviewers table to "A" . You can see this change if you print out the reviewers table:

>>>
>>> select_query = """
... SELECT first_name, last_name
... FROM reviewers
... """
>>> with connection.cursor() as cursor:
...     cursor.execute(select_query)
...     for reviewer in cursor.fetchall():
...         print(reviewer)
...
('Chaitanya', 'A')
('Mary', 'A')
('John', 'A')
('Thomas', 'A')
('Penny', 'A')
('Mitchell', 'A')
('Wyatt', 'A')
('Andre', 'A')
('Sheldon', 'A')
('Kimbra', 'A')
('Kat', 'A')
('Bruce', 'A')
('Domingo', 'A')
('Rajesh', 'A')
('Ben', 'A')
('Mahinder', 'A')
('Akbar', 'A')
('Howard', 'A')
('Pinkie', 'A')
('Gurkaran', 'A')
('Amy', 'A')
('Marlon', 'A')

The above code displays the first_name and last_name for all records in the reviewers table. The SQL injection attack corrupted this table by changing the last_name of all records to "A" .

There’s a quick fix to prevent such attacks. Don’t add the query values provided by the user directly to your query string. Instead, update the modify_ratings.py script to send these query values as arguments to .execute() :

from getpass import getpass
from mysql.connector import connect, Error

movie_id = input("Enter movie id: ")
reviewer_id = input("Enter reviewer id: ")
new_rating = input("Enter new rating: ")
update_query = """
UPDATE
    ratings
SET
    rating = %s
WHERE
    movie_id = %s AND reviewer_id = %s;

SELECT *
FROM ratings
WHERE
    movie_id = %s AND reviewer_id = %s
"""
val_tuple = (
    new_rating,
    movie_id,
    reviewer_id,
    movie_id,
    reviewer_id,
)

try:
    with connect(
        host="localhost",
        user=input("Enter username: "),
        password=getpass("Enter password: "),
        database="online_movie_rating",
    ) as connection:
        with connection.cursor() as cursor:
            for result in cursor.execute(update_query, val_tuple, multi=True):
                if result.with_rows:
                    print(result.fetchall())
            connection.commit()
except Error as e:
    print(e)

Notice that the %s placeholders are no longer in string quotes. Strings passed to the placeholders might contain some special characters. If necessary, these can be correctly escaped by the underlying library.

cursor.execute() makes sure that the values in the tuple received as argument are of the required data type. If a user tries to sneak in some problematic characters, then the code will raise an exception:

$ python modify_ratings.py
Enter movie id: 18
Enter reviewer id: 15"; UPDATE reviewers SET last_name = "A
Enter new rating: 5.0
Enter username: <user_name>
Enter password:
1292 (22007): Truncated incorrect DOUBLE value: '15";
UPDATE reviewers SET last_name = "A'

cursor.execute() will raise an exception if it finds any unwanted characters in the user input. You should use this approach whenever you incorporate user input in a query. There are other ways of preventing SQL injection attacks as well.



DELETE Command

Deleting records works very similarly to updating records. You use the DELETE statement to remove selected records.

Note: Deleting is an irreversible proces. If you don’t use the WHERE clause, then all records from the specified table will be deleted. You’ll need to run the INSERT INTO query again to get back the deleted records.

It’s recommended that you first run a SELECT query with the same filter to make sure that you’re deleting the right records. For example, to remove all ratings given by reviewer_id = 2 , you should first run the corresponding SELECT query:

>>>
>>> select_movies_query = """
... SELECT reviewer_id, movie_id FROM ratings
... WHERE reviewer_id = 2
... """
>>> with connection.cursor() as cursor:
...     cursor.execute(select_movies_query)
...     for movie in cursor.fetchall():
...         print(movie)
...
(2, 7)
(2, 8)
(2, 12)
(2, 23)

The above code snippet outputs the reviewer_id and movie_id for records in the ratings table where reviewer_id = 2 . Once you’ve confirmed that these are the records that you need to delete, you can run a DELETE query with the same filter:

delete_query = "DELETE FROM ratings WHERE reviewer_id = 2"
with connection.cursor() as cursor:
    cursor.execute(delete_query)
    connection.commit()

With this query, you remove all ratings given by the reviewer with reviewer_id = 2 from the ratings table.




Other Ways to Connect Python and MySQL

In this tutorial, you saw MySQL Connector/Python, which is the officially recommended means of interacting with a MySQL database from a Python application. There are two other popular connectors:

  1. mysqlclient is a library that is a close competitor to the official connector and is actively updated with new features. Because its core is written in C, it has better performance than the pure-Python official connector. A big drawback is that it’s fairly difficult to set up and install, especially on Windows.

  2. MySQLdb is a legacy software that’s still used in commercial applications. It’s written in C and is faster than MySQL Connector/Python but is available only for Python 2.

These connectors act as interfaces between your program and a MySQL database, and you send your SQL queries through them. But many developers prefer using an object-oriented paradigm rather than SQL queries to manipulate data.

Object-relational mapping (ORM) is a technique that allows you to query and manipulate data from a database directly using an object-oriented language. An ORM library encapsulates the code needed to manipulate data, which eliminates the need to use even a tiny bit of SQL. Here are the most popular Python ORMs for SQL-based databases:

  1. SQLAlchemy is an ORM that facilitates communication between Python and other SQL databases. You can create different engines for different databases like MySQL, PostgreSQL, SQLite, and so on. SQLAlchemy is commonly used alongside the pandas library to provide complete data-handling functionality.

  2. peewee is a lightweight and fast ORM that’s quick to set up. This is quite useful when your interaction with the database is limited to extracting a few records. For example, if you need to copy selected records from a MySQL database into a CSV file, then peewee might be your best choice.

  3. Django ORM is one of the most powerful features of Django and is supplied alongside the Django web framework. It can interact with a variety of databases such as SQLite, PostgreSQL, and MySQL. Many Django-based applications use the Django ORM for data modeling and basic queries but often switch to SQLAlchemy for more complex requirements.

You might find one of these approaches to be more suitable for your application. If you’re not sure which one to use, then it’s best to go with the officially recommended MySQL Connector/Python that you saw in action in this tutorial.



Conclusion

In this tutorial, you saw how to use MySQL Connector/Python to integrate a MySQL database with your Python application. You also saw some unique features of a MySQL database that differentiate it from other SQL databases.

Along the way, you learned some programming best practices that are worth considering when it comes to establishing a connection, creating tables, and inserting and updating records in a database application. You also developed a sample MySQL database for an online movie rating system and interacted with it directly from your Python application.

In this tutorial, you learned how to:

  • Connect your Python app with a MySQL database
  • Bring data from a MySQL database into Python for further analysis
  • Execute SQL queries from your Python application
  • Handle exceptions while accessing the database
  • Prevent SQL injection attacks on your application

If you’re interested, Python also has connectors for other DBMSs like MongoDB and PostgreSQL. For more information, check out Python Database Tutorials.



  1. Připojení Delphi na Linuxu k SQL Serveru

  2. Bylo by možné při provádění PITR pozastavit/obnovit v PostgreSQL?

  3. Hash Co? Pochopení hash indexů

  4. Jak zašifrovat uživatelem definovanou funkci na serveru SQL Server