SQL UNIQUE Constraint

SQL Tutorial › Database Design › UNIQUE

SQL UNIQUE Constraint

BeginnerLesson 52 of 698 min read6 queries run on MySQL 8.4

A UNIQUE constraint guarantees that no two rows share the same value in a column, or the same combination of values in several columns. Use it for natural identifiers that are not the primary key: email addresses, usernames, product codes, “one review per user per product”.

In this lesson
  • Make a column unique
  • Make a combination of columns unique
  • Understand how UNIQUE treats NULL
  • Add and drop unique constraints, and compare with PRIMARY KEY

A unique column

SQL
CREATE TABLE users (  user_id  INT PRIMARY KEY,  username VARCHAR(30) NOT NULL UNIQUE,  email    VARCHAR(100) UNIQUE);INSERT INTO users VALUES (1, 'asha', 'asha@example.com'), (2, 'ravi', 'ravi@example.com');SELECT * FROM users;
ResultMySQL 8.4
mysql> CREATE TABLE users (
Query OK, 0 rows affected
mysql> INSERT INTO users VALUES (1, 'asha', 'asha@example.com'), (2, 'ravi', …
Query OK, 2 rows affected
mysql> SELECT * FROM users
user_idusernameemail
1ashaasha@example.com
2raviravi@example.com
2 rows in set

A duplicate is rejected:

MySQL
CREATE TABLE users (user_id INT PRIMARY KEY, username VARCHAR(30) NOT NULL UNIQUE, email VARCHAR(100) UNIQUE);INSERT INTO users VALUES (1, 'asha', 'asha@example.com');INSERT INTO users VALUES (2, 'asha', 'other@example.com');
ResultMySQL 8.4
mysql> CREATE TABLE users (user_id INT PRIMARY KEY, username VARCHAR(30) NOT …
Query OK, 0 rows affected
mysql> INSERT INTO users VALUES (1, 'asha', 'asha@example.com')
Query OK, 1 row affected
mysql> INSERT INTO users VALUES (2, 'asha', 'other@example.com')
ERROR 1062 (23000): Duplicate entry 'asha' for key 'users.username'
How this query works, step by step
  1. The first row is inserted.
  2. The second row has a different id but the same username, so MySQL rejects it with error 1062 and names the key: users.username.
  3. With the default case-insensitive collation, 'Asha' would also count as a duplicate of 'asha'.

UNIQUE and NULL

A unique column may hold many NULLs, because NULL is not equal to anything, not even another NULL:

SQL
CREATE TABLE users (user_id INT PRIMARY KEY, username VARCHAR(30) NOT NULL UNIQUE, email VARCHAR(100) UNIQUE);INSERT INTO users VALUES (1, 'asha', NULL), (2, 'ravi', NULL), (3, 'mona', NULL);SELECT COUNT(*) AS users_without_email FROM users WHERE email IS NULL;
ResultMySQL 8.4
mysql> CREATE TABLE users (user_id INT PRIMARY KEY, username VARCHAR(30) NOT …
Query OK, 0 rows affected
mysql> INSERT INTO users VALUES (1, 'asha', NULL), (2, 'ravi', NULL), (3, 'mo…
Query OK, 3 rows affected
mysql> SELECT COUNT(*) AS users_without_email FROM users WHERE email IS NULL
users_without_email
3
1 row in set

Add NOT NULL if every row must have a distinct, real value.

Composite unique key

One review per customer per product: the pair must be unique, each column alone may repeat:

SQL
CREATE TABLE reviews (  review_id   INT PRIMARY KEY,  customer_id INT NOT NULL,  product_id  INT NOT NULL,  rating      INT NOT NULL,  CONSTRAINT uq_review UNIQUE (customer_id, product_id));INSERT INTO reviews VALUES (1, 1, 2, 5), (2, 1, 4, 4), (3, 2, 2, 3);SELECT * FROM reviews;
ResultMySQL 8.4
mysql> CREATE TABLE reviews (
Query OK, 0 rows affected
mysql> INSERT INTO reviews VALUES (1, 1, 2, 5), (2, 1, 4, 4), (3, 2, 2, 3)
Query OK, 3 rows affected
mysql> SELECT * FROM reviews
review_idcustomer_idproduct_idrating
1125
2144
3223
3 rows in set
MySQL
CREATE TABLE reviews (review_id INT PRIMARY KEY, customer_id INT NOT NULL, product_id INT NOT NULL, rating INT NOT NULL, CONSTRAINT uq_review UNIQUE (customer_id, product_id));INSERT INTO reviews VALUES (1, 1, 2, 5);INSERT INTO reviews VALUES (4, 1, 2, 1);
ResultMySQL 8.4
mysql> CREATE TABLE reviews (review_id INT PRIMARY KEY, customer_id INT NOT N…
Query OK, 0 rows affected
mysql> INSERT INTO reviews VALUES (1, 1, 2, 5)
Query OK, 1 row affected
mysql> INSERT INTO reviews VALUES (4, 1, 2, 1)
ERROR 1062 (23000): Duplicate entry '1-2' for key 'reviews.uq_review'
How this query works, step by step
  1. Customer 1 may review products 2 and 4, and customer 2 may also review product 2.
  2. A second review by customer 1 of product 2 repeats the pair (1, 2) and is rejected.

Add and drop UNIQUE

MySQL
ALTER TABLE customers ADD CONSTRAINT uq_customer_email UNIQUE (email);SHOW INDEX FROM customers WHERE Key_name = 'uq_customer_email';ALTER TABLE customers DROP INDEX uq_customer_email;
ResultMySQL 8.4
mysql> ALTER TABLE customers ADD CONSTRAINT uq_customer_email UNIQUE (email)
Query OK, 0 rows affected
mysql> SHOW INDEX FROM customers WHERE Key_name = 'uq_customer_email'
TableNon_uniqueKey_nameSeq_in_indexColumn_nameCollationCardinalitySub_partPackedNullIndex_typeCommentIndex_commentVisibleExpression
customers0uq_customer_email1emailA7NULLNULLYESBTREEYESNULL
1 row in set
mysql> ALTER TABLE customers DROP INDEX uq_customer_email
Query OK, 0 rows affected
How this query works, step by step
  1. In MySQL a unique constraint is implemented as a unique index, which also speeds up lookups by email.
  2. SHOW INDEX lists it; Non_unique = 0 means unique.
  3. It is dropped with DROP INDEX (or DROP CONSTRAINT in MySQL 8.0.19+).

UNIQUE vs PRIMARY KEY

PRIMARY KEYUNIQUE
Per tableonemany
NULL allowednoyes (many)
Purposethe row’s identity, target of foreign keysbusiness rules on other columns
InnoDB storagerows are stored in primary-key orderseparate index

Quick quiz

1. How many NULLs can a UNIQUE column hold in MySQL?

2. UNIQUE (customer_id, product_id) rejects…

3. How many UNIQUE constraints can a table have?

UNIQUE FAQ

What is a UNIQUE constraint in SQL?

A rule that no two rows may have the same value (or combination of values) in the constrained columns.

Can a UNIQUE column be NULL?

Yes. In MySQL a unique column can contain multiple NULLs; add NOT NULL to prevent them.

Is a UNIQUE constraint an index?

In MySQL, yes: each unique constraint creates a unique index, which also speeds up searches on those columns.

SQL FOREIGN KEY

SQL Tutorial › Database Design › FOREIGN KEY

SQL FOREIGN KEY

IntermediateLesson 54 of 6912 min read6 queries run on MySQL 8.4

A foreign key links a column in one table (the child) to the primary key of another (the parent). The database then guarantees referential integrity: no order for a customer who does not exist, no employee in a department that was deleted. This lesson shows the errors a foreign key raises and the actions (CASCADE, SET NULL, RESTRICT) that decide what happens when a parent row changes.

In this lesson
  • Create a foreign key between parent and child tables
  • Understand errors 1452 (bad child) and 1451 (parent in use)
  • Choose ON DELETE / ON UPDATE actions
  • Add and drop foreign keys

Parent and child

In the sample database, orders.customer_id references customers.customer_id:

customers · 7 rows (some columns)
customer_idcustomer_name
1Ananya Sharma
2Rohit Kumar
3Fatima Khan
4David Fernandes
5Ishita Bose
6Manoj Pillai
7Sara Thomas
orders · 10 rows
order_idcustomer_idorder_datestatus
100112025-01-05Delivered
100222025-01-17Delivered
100312025-02-02Delivered
100432025-02-14Cancelled
100542025-03-08Delivered
100652025-03-22Shipped
100722025-04-10Delivered
100812025-04-28Pending
100932025-05-15Delivered
101052025-06-01Delivered
  • customers is the parent table; orders is the child.
  • Every orders.customer_id must exist in customers.

Create a foreign key

SQL
CREATE TABLE teams (  team_id   INT PRIMARY KEY,  team_name VARCHAR(30) NOT NULL);CREATE TABLE players (  player_id INT PRIMARY KEY,  name      VARCHAR(30) NOT NULL,  team_id   INT,  CONSTRAINT fk_player_team FOREIGN KEY (team_id) REFERENCES teams (team_id));INSERT INTO teams VALUES (1, 'Testers'), (2, 'Developers');INSERT INTO players VALUES (10, 'Asha', 1), (11, 'Ravi', 2), (12, 'Mona', NULL);SELECT p.name, t.team_name FROM players p LEFT JOIN teams t ON t.team_id = p.team_id;
ResultMySQL 8.4
mysql> CREATE TABLE teams (
Query OK, 0 rows affected
mysql> CREATE TABLE players (
Query OK, 0 rows affected
mysql> INSERT INTO teams VALUES (1, 'Testers'), (2, 'Developers')
Query OK, 2 rows affected
mysql> INSERT INTO players VALUES (10, 'Asha', 1), (11, 'Ravi', 2), (12, 'Mon…
Query OK, 3 rows affected
mysql> SELECT p.name, t.team_name FROM players p LEFT JOIN teams t ON t.team_…
nameteam_name
AshaTesters
RaviDevelopers
MonaNULL
3 rows in set
How this query works, step by step
  1. The parent table teams must exist first, with a primary (or unique) key.
  2. FOREIGN KEY (team_id) REFERENCES teams (team_id) ties players.team_id to it.
  3. Mona has NULL: a nullable foreign key means “not assigned”, which is allowed.
  4. MySQL automatically creates an index on players.team_id for the foreign key.

Error 1452: child row without a parent

MySQL
INSERT INTO orders (order_id, customer_id, order_date, status) VALUES (2001, 99, '2026-01-10', 'Pending');
ResultMySQL 8.4
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`company`.`orders`, CONSTRAINT `orders_ibfk_1` FOREIGN KEY (`customer_id`) REFERENCES `customers` (`customer_id`))

Error 1451: parent row still in use

MySQL
DELETE FROM customers WHERE customer_id = 1;
ResultMySQL 8.4
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`company`.`orders`, CONSTRAINT `orders_ibfk_1` FOREIGN KEY (`customer_id`) REFERENCES `customers` (`customer_id`))
How this query works, step by step
  1. Customer 99 does not exist, so the new order is rejected (1452).
  2. Customer 1 has orders, so deleting the customer would orphan them (1451).
  3. The default action is RESTRICT / NO ACTION: refuse the change.

ON DELETE CASCADE

With ON DELETE CASCADE, deleting a parent row deletes its child rows automatically:

MySQL
CREATE TABLE teams (team_id INT PRIMARY KEY, team_name VARCHAR(30) NOT NULL);CREATE TABLE players (  player_id INT PRIMARY KEY,  name      VARCHAR(30) NOT NULL,  team_id   INT,  FOREIGN KEY (team_id) REFERENCES teams (team_id) ON DELETE CASCADE);INSERT INTO teams VALUES (1, 'Testers'), (2, 'Developers');INSERT INTO players VALUES (10, 'Asha', 1), (11, 'Ravi', 2), (12, 'Karan', 2);DELETE FROM teams WHERE team_id = 2;SELECT * FROM players;
ResultMySQL 8.4
mysql> CREATE TABLE teams (team_id INT PRIMARY KEY, team_name VARCHAR(30) NOT…
Query OK, 0 rows affected
mysql> CREATE TABLE players (
Query OK, 0 rows affected
mysql> INSERT INTO teams VALUES (1, 'Testers'), (2, 'Developers')
Query OK, 2 rows affected
mysql> INSERT INTO players VALUES (10, 'Asha', 1), (11, 'Ravi', 2), (12, 'Kar…
Query OK, 3 rows affected
mysql> DELETE FROM teams WHERE team_id = 2
Query OK, 1 row affected
mysql> SELECT * FROM players
player_idnameteam_id
10Asha1
1 row in set
How this query works, step by step
  1. Team 2 has two players.
  2. DELETE FROM teams WHERE team_id = 2 removes the team and both of its players.
  3. MySQL reports only 1 row affected (the team); the cascaded rows are not counted.
Watch out

CASCADE is powerful and silent. One DELETE on a parent can remove thousands of child rows. Use it for true “part of” relationships (an order’s lines) and not for important independent data.

ON DELETE SET NULL

MySQL
CREATE TABLE teams (team_id INT PRIMARY KEY, team_name VARCHAR(30) NOT NULL);CREATE TABLE players (  player_id INT PRIMARY KEY,  name      VARCHAR(30) NOT NULL,  team_id   INT,  FOREIGN KEY (team_id) REFERENCES teams (team_id) ON DELETE SET NULL);INSERT INTO teams VALUES (1, 'Testers'), (2, 'Developers');INSERT INTO players VALUES (10, 'Asha', 1), (11, 'Ravi', 2);DELETE FROM teams WHERE team_id = 2;SELECT * FROM players;
ResultMySQL 8.4
mysql> CREATE TABLE teams (team_id INT PRIMARY KEY, team_name VARCHAR(30) NOT…
Query OK, 0 rows affected
mysql> CREATE TABLE players (
Query OK, 0 rows affected
mysql> INSERT INTO teams VALUES (1, 'Testers'), (2, 'Developers')
Query OK, 2 rows affected
mysql> INSERT INTO players VALUES (10, 'Asha', 1), (11, 'Ravi', 2)
Query OK, 2 rows affected
mysql> DELETE FROM teams WHERE team_id = 2
Query OK, 1 row affected
mysql> SELECT * FROM players
player_idnameteam_id
10Asha1
11RaviNULL
2 rows in set

Ravi stays, with team_id set to NULL: the player exists, the team does not.

The actions

ActionWhen the parent row is deleted (or its key updated)
RESTRICT / NO ACTION (default)refuse the change while children exist
CASCADEdelete (or update) the child rows too
SET NULLset the child’s foreign key column to NULL
SET DEFAULTnot supported by InnoDB

ON UPDATE CASCADE works the same way for changes to the parent’s key value.

Add and drop a foreign key

MySQL
CREATE TABLE reviews (review_id INT PRIMARY KEY, product_id INT, rating INT);ALTER TABLE reviews  ADD CONSTRAINT fk_review_product FOREIGN KEY (product_id) REFERENCES products (product_id);SELECT constraint_name, referenced_table_nameFROM information_schema.referential_constraintsWHERE constraint_schema = 'company' AND table_name = 'reviews';ALTER TABLE reviews DROP FOREIGN KEY fk_review_product;
ResultMySQL 8.4
mysql> CREATE TABLE reviews (review_id INT PRIMARY KEY, product_id INT, ratin…
Query OK, 0 rows affected
mysql> ALTER TABLE reviews
Query OK, 0 rows affected
mysql> SELECT constraint_name, referenced_table_name
CONSTRAINT_NAMEREFERENCED_TABLE_NAME
fk_review_productproducts
1 row in set
mysql> ALTER TABLE reviews DROP FOREIGN KEY fk_review_product
Query OK, 0 rows affected

Rules for a valid foreign key

  • The parent column must be a primary key or have a unique index.
  • Both columns must have the same type (INT to INT, same sign and length for strings).
  • Both tables must use InnoDB (the default).
  • Existing child values must already exist in the parent when you add the key.

Quick quiz

1. Which table does the foreign key constraint live on?

2. What happens with ON DELETE CASCADE when a parent row is deleted?

3. Error 1452 means…

4. Can a foreign key column be NULL?

Foreign key FAQ

What is a foreign key in SQL?

A column whose values must match the primary or unique key of another table, so related rows always exist.

What is ON DELETE CASCADE?

An option on a foreign key: when a parent row is deleted, all child rows referencing it are deleted automatically.

How do I fix “Cannot add or update a child row: a foreign key constraint fails”?

Insert the parent row first, or correct the child value so it matches an existing parent key.

Do foreign keys slow down inserts?

Slightly, because each insert checks the parent index. The protection against orphaned data is almost always worth it.

SQL PRIMARY KEY

SQL Tutorial › Database Design › PRIMARY KEY

SQL PRIMARY KEY

BeginnerLesson 53 of 699 min read7 queries run on MySQL 8.4

The primary key is the column (or set of columns) that identifies each row uniquely. It cannot be NULL, cannot repeat, and is what other tables point to with foreign keys. Every table should have one, and choosing it well is one of the first decisions in database design.

In this lesson
  • Define single-column and composite primary keys
  • Understand the errors a primary key prevents
  • Choose between natural and surrogate keys
  • Add, drop and inspect a primary key

Define a primary key

SQL
CREATE TABLE books (  book_id INT PRIMARY KEY,  isbn    CHAR(13) NOT NULL UNIQUE,  title   VARCHAR(100) NOT NULL);INSERT INTO books VALUES (1, '9780134685991', 'Effective Java'), (2, '9781492056355', 'Learning SQL');SELECT * FROM books;
ResultMySQL 8.4
mysql> CREATE TABLE books (
Query OK, 0 rows affected
mysql> INSERT INTO books VALUES (1, '9780134685991', 'Effective Java'), (2, '…
Query OK, 2 rows affected
mysql> SELECT * FROM books
book_idisbntitle
19780134685991Effective Java
29781492056355Learning SQL
2 rows in set
How this query works, step by step
  1. book_id INT PRIMARY KEY makes book_id unique and NOT NULL.
  2. isbn is also unique, but it is a business value; the short integer book_id is the key other tables will reference.

What a primary key prevents

MySQL
CREATE TABLE books (book_id INT PRIMARY KEY, title VARCHAR(100) NOT NULL);INSERT INTO books VALUES (1, 'Effective Java');INSERT INTO books VALUES (1, 'Learning SQL');
ResultMySQL 8.4
mysql> CREATE TABLE books (book_id INT PRIMARY KEY, title VARCHAR(100) NOT NU…
Query OK, 0 rows affected
mysql> INSERT INTO books VALUES (1, 'Effective Java')
Query OK, 1 row affected
mysql> INSERT INTO books VALUES (1, 'Learning SQL')
ERROR 1062 (23000): Duplicate entry '1' for key 'books.PRIMARY'
MySQL
CREATE TABLE books (book_id INT PRIMARY KEY, title VARCHAR(100) NOT NULL);INSERT INTO books VALUES (NULL, 'Learning SQL');
ResultMySQL 8.4
mysql> CREATE TABLE books (book_id INT PRIMARY KEY, title VARCHAR(100) NOT NU…
Query OK, 0 rows affected
mysql> INSERT INTO books VALUES (NULL, 'Learning SQL')
ERROR 1048 (23000): Column 'book_id' cannot be null
How this query works, step by step
  1. Error 1062: a second row with book_id = 1 is a duplicate entry for key PRIMARY.
  2. Error 1048: the key cannot be NULL.

A table can have only one primary key:

MySQL
CREATE TABLE t (a INT PRIMARY KEY, b INT PRIMARY KEY);
ResultMySQL 8.4
ERROR 1068 (42000): Multiple primary key defined

Composite primary key

When no single column is unique, the key can be a combination. In order_items, an order has many products and a product appears in many orders, but each (order_id, product_id) pair appears once:

MySQL
SHOW KEYS FROM order_items WHERE Key_name = 'PRIMARY';
ResultMySQL 8.4
TableNon_uniqueKey_nameSeq_in_indexColumn_nameCollationCardinalitySub_partPackedNullIndex_typeCommentIndex_commentVisibleExpression
order_items0PRIMARY1order_idA1NULLNULLBTREEYESNULL
order_items0PRIMARY2product_idA1NULLNULLBTREEYESNULL
2 rows in set
MySQL
INSERT INTO order_items (order_id, product_id, quantity) VALUES (1001, 2, 3);
ResultMySQL 8.4
ERROR 1062 (23000): Duplicate entry '1001-2' for key 'order_items.PRIMARY'
How this query works, step by step
  1. SHOW KEYS lists the two columns of the primary key in order (Seq_in_index 1 and 2).
  2. Order 1001 already contains product 2, so the same pair is rejected; to change the quantity, UPDATE the existing line.

Natural vs surrogate keys

Natural keySurrogate key
Exampleemail, ISBN, PAN numbercustomer_id INT AUTO_INCREMENT
Meaningreal-world valuenone, just a number
Can change?yes (emails change)never
Sizeoften long text4 or 8 bytes

Most designs use a surrogate primary key (often AUTO_INCREMENT) and protect the natural identifier with a UNIQUE constraint, as the books table above does with isbn.

Tip

In InnoDB, rows are physically stored in primary-key order and every secondary index stores the primary key. A short, ever-increasing key (such as an auto-increment integer) keeps tables and indexes compact and inserts fast.

Add or drop a primary key

MySQL
CREATE TABLE visits (visitor VARCHAR(30), visit_date DATE, pages INT);INSERT INTO visits VALUES ('asha', '2026-01-01', 3), ('asha', '2026-01-02', 5);ALTER TABLE visits ADD PRIMARY KEY (visitor, visit_date);SHOW KEYS FROM visits WHERE Key_name = 'PRIMARY';
ResultMySQL 8.4
mysql> CREATE TABLE visits (visitor VARCHAR(30), visit_date DATE, pages INT)
Query OK, 0 rows affected
mysql> INSERT INTO visits VALUES ('asha', '2026-01-01', 3), ('asha', '2026-01…
Query OK, 2 rows affected
mysql> ALTER TABLE visits ADD PRIMARY KEY (visitor, visit_date)
Query OK, 0 rows affected
mysql> SHOW KEYS FROM visits WHERE Key_name = 'PRIMARY'
TableNon_uniqueKey_nameSeq_in_indexColumn_nameCollationCardinalitySub_partPackedNullIndex_typeCommentIndex_commentVisibleExpression
visits0PRIMARY1visitorA1NULLNULLBTREEYESNULL
visits0PRIMARY2visit_dateA2NULLNULLBTREEYESNULL
2 rows in set
How this query works, step by step
  1. The table is created without a key.
  2. ALTER TABLE ... ADD PRIMARY KEY adds a composite key; it works because the existing rows are unique and not NULL.
  3. ALTER TABLE visits DROP PRIMARY KEY; would remove it again.

Quick quiz

1. How many primary keys can a table have?

2. Can a primary key column contain NULL?

3. What is a surrogate key?

Primary key FAQ

What is a primary key in SQL?

A column or group of columns whose values uniquely identify each row. It must be unique and cannot be NULL.

What is a composite primary key?

A primary key made of two or more columns, where only the combination must be unique, e.g. (order_id, product_id).

What is the difference between primary key and unique key?

A table has one primary key and it cannot contain NULL; it can have many unique keys, which may contain NULLs.

Should every table have a primary key?

Yes. Without one, rows cannot be identified reliably, and InnoDB creates a hidden key that you cannot use.

Python SQLite

Python Tutorial › Libraries & Databases › SQLite

Python SQLite

IntermediateLesson 47 of 4712 min read8 runnable examples

SQLite is a complete SQL database stored in a single file, and Python includes the sqlite3 module to use it, with nothing to install. It is ideal for small apps, test data and learning SQL from Python.

In this lesson
  • Connect and create tables
  • Insert rows safely with parameters
  • Query, update and delete
  • Use transactions and load results into pandas

Connect and create a table

sqlite3.connect() opens a database file, creating it if it does not exist. A cursor runs SQL statements.

Python
import sqlite3 conn = sqlite3.connect("shop.db")cur = conn.cursor()cur.execute("DROP TABLE IF EXISTS products")cur.execute("""    CREATE TABLE products (        id INTEGER PRIMARY KEY AUTOINCREMENT,        name TEXT NOT NULL,        category TEXT,        price REAL,        stock INTEGER DEFAULT 0    )""")conn.commit()print(cur.execute("SELECT name FROM sqlite_master WHERE type='table'").fetchall())conn.close()
Output
[('products',), ('sqlite_sequence',)]
Tip

sqlite3.connect(":memory:") creates a temporary database in memory, which is perfect for tests.

Insert rows with parameters

Use ? placeholders and pass the values separately. Never build SQL with f-strings from user input; that opens the door to SQL injection.

Python
import sqlite3 conn = sqlite3.connect("shop.db")cur = conn.cursor()cur.execute("INSERT INTO products (name, category, price, stock) VALUES (?, ?, ?, ?)",            ("Keyboard", "electronics", 1499.0, 25)) items = [    ("Mouse", "electronics", 349.0, 60),    ("Notebook", "stationery", 45.0, 300),    ("Pen", "stationery", 10.0, 0),    ("Monitor", "electronics", 12999.0, 8),]cur.executemany("INSERT INTO products (name, category, price, stock) VALUES (?, ?, ?, ?)", items)conn.commit()print("last id:", cur.lastrowid, "rows:", cur.execute("SELECT COUNT(*) FROM products").fetchone()[0])conn.close()
Output
last id: 1 rows: 5

Query rows

Python
import sqlite3 conn = sqlite3.connect("shop.db")cur = conn.cursor() for row in cur.execute("SELECT id, name, price FROM products ORDER BY price DESC LIMIT 3"):    print(row) cur.execute("SELECT name FROM products WHERE category = ? AND stock > ?", ("electronics", 10))print(cur.fetchall()) print(cur.execute("SELECT AVG(price) FROM products WHERE category = 'stationery'").fetchone())conn.close()
Output
(5, 'Monitor', 12999.0)
(1, 'Keyboard', 1499.0)
(2, 'Mouse', 349.0)
[('Keyboard',), ('Mouse',)]
(27.5,)
MethodReturns
fetchone()the next row as a tuple, or None
fetchmany(n)a list of up to n rows
fetchall()a list of all remaining rows

Rows as dictionaries

Set row_factory to sqlite3.Row to read columns by name:

Python
import sqlite3 conn = sqlite3.connect("shop.db")conn.row_factory = sqlite3.Rowrow = conn.execute("SELECT * FROM products WHERE name = ?", ("Mouse",)).fetchone()print(row["name"], row["price"], row["stock"])print(dict(row))conn.close()
Output
Mouse 349.0 60
{'id': 2, 'name': 'Mouse', 'category': 'electronics', 'price': 349.0, 'stock': 60}

Update and delete

Python
import sqlite3 conn = sqlite3.connect("shop.db")cur = conn.cursor()cur.execute("UPDATE products SET price = ROUND(price * 0.9, 2) WHERE category = ?", ("electronics",))print("discounted:", cur.rowcount)cur.execute("DELETE FROM products WHERE stock = 0")print("deleted:", cur.rowcount)conn.commit()print(conn.execute("SELECT name, price FROM products ORDER BY id").fetchall())conn.close()
Output
discounted: 3
deleted: 1
[('Keyboard', 1349.1), ('Mouse', 314.1), ('Notebook', 45.0), ('Monitor', 11699.1)]

Transactions

Changes become permanent only on commit(); rollback() undoes everything since the last commit. Using the connection in a with block commits on success and rolls back on an error:

Python
import sqlite3 conn = sqlite3.connect("shop.db")try:    with conn:        conn.execute("UPDATE products SET stock = stock - 5 WHERE name = 'Monitor'")        conn.execute("INSERT INTO products (name) VALUES (NULL)")   # violates NOT NULLexcept sqlite3.IntegrityError as e:    print("rolled back:", e) print(conn.execute("SELECT stock FROM products WHERE name = 'Monitor'").fetchone())conn.close()
Output
rolled back: NOT NULL constraint failed: products.name
(8,)

The stock is still 8 because the whole transaction was rolled back when the second statement failed.

Join two tables

Python
import sqlite3 conn = sqlite3.connect(":memory:")conn.executescript("""    CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT);    CREATE TABLE orders (id INTEGER PRIMARY KEY, user_id INTEGER, amount REAL);    INSERT INTO users VALUES (1, 'Asha'), (2, 'Ravi'), (3, 'Meena');    INSERT INTO orders VALUES (1, 1, 500), (2, 1, 250), (3, 3, 900);""")query = """    SELECT u.name, COUNT(o.id), COALESCE(SUM(o.amount), 0)    FROM users u LEFT JOIN orders o ON o.user_id = u.id    GROUP BY u.id ORDER BY u.name"""for row in conn.execute(query):    print(row)conn.close()
Output
('Asha', 2, 750.0)
('Meena', 1, 900.0)
('Ravi', 0, 0)

SQLite with pandas

Python
import sqlite3import pandas as pd conn = sqlite3.connect("shop.db")df = pd.read_sql_query("SELECT name, category, price FROM products", conn)print(df)print(df.groupby("category")["price"].mean().round(1).to_dict())conn.close()
Output
       name     category    price
0  Keyboard  electronics   1349.1
1     Mouse  electronics    314.1
2  Notebook   stationery     45.0
3   Monitor  electronics  11699.1
{'electronics': 4454.1, 'stationery': 45.0}

Check your understanding

Quick quiz

1. Why use ? placeholders instead of f-strings in SQL?

2. What makes inserted rows permanent?

3. Which returns a single row?

Exercise: student marks database

Create an in-memory table of students and marks, then print the average mark and the names of students above the average.

Input
("Asha", 88), ("Ravi", 64), ("Meena", 93), ("John", 71)
Expected output
Average: 79.0
Above average: ['Meena', 'Asha']
Hint 1

A subquery works: WHERE marks > (SELECT AVG(marks) FROM students).

Program Practice

20 Python SQLite Programs

Every program has a step-by-step explanation, colour-coded code and its real output.

Start practising →
Related sets:All practice sets

Python SQLite FAQ

Do I need to install SQLite for Python?

No. The sqlite3 module and the SQLite engine come with Python.

How do I see the column names of a query result?

Read cursor.description (the first item of each entry is the name), or set conn.row_factory = sqlite3.Row and call row.keys().

Is SQLite good for production?

It is excellent for local apps, tools, tests and small to medium sites with few concurrent writers. Use PostgreSQL or MySQL for many simultaneous writers.

Python JSON Module Tutorial

Python JSON Module Tutorial

Introduction

Welcome to our comprehensive guide on Python’s json module! In the world of data interchange and storage, JSON (JavaScript Object Notation) plays a pivotal role as a lightweight and human-readable format. Python’s json module equips developers with powerful tools to effortlessly handle JSON data, facilitating data serialization, deserialization, and manipulation. In this tutorial, we’ll embark on a journey through the capabilities of the json module, exploring its features, comparing it to other modules, and delving into a wide array of functions and methods with real-world examples.

Features

Python’s json module offers a range of features that make it an essential tool for working with JSON data:

  • Serialization: Convert Python objects into JSON-encoded strings.
  • Deserialization: Parse JSON-encoded strings into Python objects.
  • Human-Readable: JSON data is easily readable by both humans and machines.
  • Data Integrity: JSON ensures data integrity through structured representation.

How it is Different from Other Modules

While Python offers various modules for data manipulation and storage, the json module excels in its specialization for handling JSON data. Unlike general-purpose modules, the json module specifically addresses the challenges of working with JSON-encoded information, ensuring accurate data conversion and seamless interoperability with other systems.

Different Functions/Methods of the json Module with Examples

  1. json.dumps() – Serialize to JSON:

The dumps() function serializes Python objects to a JSON-encoded string.

				
					import json
data = {"name": "Alice", "age": 30}
json_string = json.dumps(data)
print(json_string)

				
			
  1. json.loads() – Deserialize from JSON:

The loads() function parses a JSON-encoded string into a Python object.

				
					import json
json_string = '{"name": "Alice", "age": 30}'
data = json.loads(json_string)
print(data["name"])

				
			
  1. json.dump() – Serialize to File:

The dump() function serializes Python objects to a JSON file.

				
					import json
data = {"name": "Alice", "age": 30}
with open("data.json", "w") as json_file:
    json.dump(data, json_file)

				
			
  1. json.load() – Deserialize from File:

The load() function parses a JSON file into a Python object.

				
					import json
with open("data.json", "r") as json_file:
    data = json.load(json_file)
print(data["age"])

				
			

Python Introduction

Python Tutorial › Getting Started › Python Introduction

Python Introduction

BeginnerLesson 2 of 478 min read4 runnable examples

Python is a general-purpose programming language known for code that is short and easy to read. This lesson explains what Python is, why it is so popular, and what happens when you run a Python program.

In this lesson

  • What Python is and who made it
  • The features that make Python popular
  • Where Python is used
  • How the interpreter runs your code

What is Python?

Python is a high-level, interpreted, general-purpose programming language.

  • High-level means you work with ideas such as lists, text and files, not with memory addresses.
  • Interpreted means you run the source file directly with the python command. There is no separate compile step to manage.
  • General-purpose means it is not tied to one job. The same language builds web servers, test frameworks and data reports.

Here is a complete Python program. It stores some test results and prints a summary:

Python
results = {"login": "pass", "search": "pass", "checkout": "fail"} passed = [name for name, status in results.items() if status == "pass"]print("Tests run:", len(results))print("Passed:", ", ".join(passed))

Output
Tests run: 3
Passed: login, search

You do not need to understand every line yet. Notice how little punctuation there is: no semicolons, no curly braces around blocks, no type declarations.

A short history

Year Event
1991 Guido van Rossum publishes the first version of Python
2000 Python 2.0 adds list comprehensions and garbage collection of cycles
2008 Python 3.0 cleans up the language and is not fully backward compatible
2020 Python 2 reaches end of life on 1 January; all new code uses Python 3

The name comes from the comedy group Monty Python, not from the snake.

Key features of Python

Feature What it means for you
Simple, readable syntax Indentation shows the structure, so code looks the same everywhere
Dynamically typed You do not declare types; a variable takes the type of its value
Batteries included The standard library handles files, JSON, CSV, dates, regex, HTTP and more
Cross-platform The same script runs on Windows, macOS and Linux
Multi-paradigm Write procedural, object-oriented or functional code
Huge ecosystem PyPI hosts packages such as pytest, Playwright, requests, NumPy and Pandas
Free and open source Python is developed by the Python Software Foundation and the community

Dynamic typing in action: the same name can hold values of different types, and type() tells you what it holds right now.

Python
value = 42print(type(value)) value = "forty-two"print(type(value))

Output
<class 'int'>
<class 'str'>

The Zen of Python

Python’s design ideas are written down as a short poem. Run import this to print it:

Python
import this

Output
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
Note

“Readability counts” and “Simple is better than complex” are the two lines you will feel most while learning. Python code is read far more often than it is written.

What is Python used for?

  • Test automation: pytest, Selenium, Playwright and requests for UI and API testing.
  • Web development: Django, Flask and FastAPI power web sites and REST APIs.
  • Data analysis: NumPy, Pandas and Matplotlib turn raw data into answers.
  • Machine learning and AI: scikit-learn, PyTorch and TensorFlow.
  • Scripting and automation: renaming files, sending reports, cleaning spreadsheets.
  • DevOps and cloud tooling: Ansible, AWS and Azure SDKs, CI scripts.

How Python runs your code

When you run python hello.py:

  1. The interpreter reads your source code and checks the syntax.
  2. It compiles the code to bytecode, a simple instruction format.
  3. The Python virtual machine executes the bytecode line by line.

You can see which interpreter is running and where with the sys module:

Python
import sys, platform print(platform.python_implementation())print(sys.version_info.major, sys.version_info.minor)

Output
CPython
3 15
Tip

The standard interpreter is called CPython because it is written in C. Other implementations exist, such as PyPy (faster for long-running code) and Pyodide, which runs Python in a browser and powers the Try it buttons on this site.

Check your understanding

Quick quiz

1. Who created Python?

2. What does “dynamically typed” mean?

3. Which version should new projects use?

Program Practice

Ready to write code? The basic programs use only variables, arithmetic and print(), so they are a good first set.

Python introduction FAQ

Is Python a compiled or interpreted language?

Both, in a sense. CPython compiles your source to bytecode and then interprets that bytecode. You only ever run one command, python file.py, so it feels interpreted.

Is Python good for beginners?

Yes. Its syntax is short and readable, error messages point to the exact line, and you can get useful results with very little code.

Is Python free?

Yes. Python is open source and free to use for personal and commercial projects.

What is the difference between Python and Java?

Java is statically typed and compiled to JVM bytecode ahead of time; Python is dynamically typed and run directly. Python programs are usually shorter, while Java catches more type errors before the program runs.

Sum of a list

Sum of a list

EasyFunction Programs · 5 of 39

Write a Python function to add up the numbers in a list.

Input
[6, 9, 4, 5, 3]
Output
27

Approach

  1. Loop and add.

Solution

Python
def total(numbers):    result = 0    for n in numbers:        result += n    return result print(total([6, 9, 4, 5, 3]))
Output
27

Learn the concept

New to this topic? Read the lesson, then come back.

More function programs

← All 39 Function Programs

Rows with missing age

Python Practice › Pandas Programs › Program 36

Rows with missing age

EasyPandas Programs · 36 of 95

Write a pandas program to select rows where age is missing.

Output
    name  age
1   John  NaN
3  Klaus  NaN

Approach

  1. isna().

Solution

Python
import numpy as npimport pandas as pddf = pd.DataFrame({"name": ["Alex", "John", "Peter", "Klaus"], "age": [30, np.nan, 29, np.nan]})print(df[df["age"].isna()])
Output
    name  age
1   John  NaN
3  Klaus  NaN

Learn the concept

New to this topic? Read the lesson, then come back.

More pandas programs

← All 95 Pandas Programs

Is one Series greater?

Is one Series greater?

EasyPandas Programs · 8 of 95

Write a pandas program to check element-wise whether one Series is greater than another.

Input
[1, 6, 9, 5], [5, 2, 4, 5]
Output
[False, True, True, False]

Approach

  1. >.

Solution

Python
import pandas as pda, b = pd.Series([1, 6, 9, 5]), pd.Series([5, 2, 4, 5])print((a > b).tolist())
Output
[False, True, True, False]

Learn the concept

New to this topic? Read the lesson, then come back.

More pandas programs

← All 95 Pandas Programs

Check an uppercase character

Check an uppercase character

EasyIf-Else Programs · 23 of 64

Write a Python program to check whether a character is uppercase.

Input
"A", "g", "5"
Output
A is an uppercase letter
g is not an uppercase letter
5 is not an uppercase letter

Approach

  1. Use the string method isupper().

Solution

Python
for ch in ["A", "g", "5"]:    if ch.isupper():        print(ch, "is an uppercase letter")    else:        print(ch, "is not an uppercase letter")
Output
A is an uppercase letter
g is not an uppercase letter
5 is not an uppercase letter

Line by line

Line 2

isupper() is True only for strings with at least one cased letter, all upper case; digits return False.

Learn the concept

New to this topic? Read the lesson, then come back.

More if-else programs

← All 64 If-Else Programs