Skip to content

Модуль 2. Основы баз данных и SQLite ​

1. Цели модуля ​

  • Понять, что такое база данных и зачем она нужна.
  • Разобраться в понятиях таблицы, записи, поля и ключа.
  • Познакомиться с SQLite как с простой учебной СУБД.
  • Освоить базовые SQL-команды.
  • Научиться работать с базой через SQLiteStudio.

2. Что такое база данных ​

2.1 Теория ​

База данных и её назначение

База данных — это место, где программа хранит данные в удобном и упорядоченном виде. Проще всего представить её как "умную таблицу", в которой можно быстро найти нужную информацию, изменить её или добавить новую.

Например, если хранить список студентов в обычном .txt файле, то очень быстро начнётся путаница: где чей возраст, как найти одного студента, как добавить нового, как не испортить старые данные. База данных нужна как раз для того, чтобы такого хаоса не было.

Основные понятия

  • таблица — набор однотипных данных;
  • запись — одна строка таблицы;
  • поле — отдельный столбец;
  • первичный ключ — поле, которое уникально определяет запись.

Например, в таблице students могут быть поля id, name, age, group_name.

Как это выглядит в реальности

Для начала удобно представлять базу данных как файл, внутри которого лежат таблицы. В каждой таблице есть:

  • структура — какие столбцы существуют и какого они типа;
  • данные — какие конкретно записи уже сохранены.

Например, если таблица students имеет поля id, name, age, group_name, то структура отвечает на вопрос "что тут вообще можно хранить", а данные отвечают на вопрос "что уже лежит в таблице прямо сейчас".

Типы данных в SQLite

В учебных примерах чаще всего встречаются такие типы:

  • INTEGER — целые числа;
  • TEXT — текст;
  • REAL — дробные числа;
  • NULL — пустое значение.

Проще говоря, тип поля подсказывает базе данных, что именно здесь должно лежать. Если поле age задумано как возраст, то логично хранить там число, а не текст "девятнадцать".

Ограничения полей

Кроме типа, у поля могут быть ограничения:

  • PRIMARY KEY — значение должно быть уникальным;
  • AUTOINCREMENT — значение будет увеличиваться автоматически;
  • NOT NULL — поле нельзя оставлять пустым;
  • UNIQUE — значения не должны повторяться.

Проще говоря, ограничения нужны для порядка. Они не дают случайно записать в таблицу что-то неправильное или пустое там, где это недопустимо.

Например, запись без имени в таблице студентов обычно не имеет смысла, поэтому для name часто ставят NOT NULL.

Почему именно SQLite

SQLite подходит для разных задач, потому что:

  • не требует отдельного сервера;
  • хранит базу в одном файле;
  • проста в установке и использовании;
  • хорошо подходит для небольших проектов;
  • легко открывается как в Python, так и в сторонних программах.

Что такое SQLiteStudio

SQLiteStudio — это графическая программа для работы с SQLite. В ней удобно:

  • создавать базу данных;
  • создавать таблицы;
  • добавлять и редактировать записи;
  • запускать SQL-запросы;
  • визуально смотреть структуру базы.

Это хороший первый шаг перед тем, как подключать базу к Python-коду. Сначала обучающиеся видят базу визуально, создают таблицу и записи вручную, а уже потом работают с ней программно.

Частые ошибки

  • Путать базу данных и таблицу.
  • Считать, что запись и поле — это одно и то же.
  • Не понимать, зачем нужен id.
  • Учить термины отдельно от примеров.

2.2 Практика ​

Задание 1. Разбираем таблицу

Цель - понять структуру таблицы.

Шаги:

  1. Представьте таблицу students.
  2. Определите поля id, name, age, group_name.
  3. Объясните, что будет храниться в одной записи.
  4. Отдельно разберите, зачем нужен id.

Задание 2. Первое знакомство с SQLiteStudio

Цель - увидеть базу данных через интерфейс программы.

Шаги:

  1. Откройте SQLiteStudio.
  2. Создайте новую базу данных.
  3. Посмотрите, как отображаются таблицы и поля.
  4. Найдите окно для выполнения SQL-запросов.

3. Базовые SQL-команды ​

3.1 Теория ​

Что такое SQL

SQL — это язык запросов для работы с базами данных. С его помощью можно создавать таблицы, добавлять записи, искать данные, изменять их и удалять.

Если совсем просто, SQL — это набор команд, которыми мы "говорим" базе данных, что нужно сделать.

В этой теме важно не просто выучить команды, а понять, какую задачу решает каждая из них.

Полезно дать такую опору:

  • CREATE — создаём структуру;
  • INSERT — добавляем новые данные;
  • SELECT — читаем данные;
  • UPDATE — меняем данные;
  • DELETE — удаляем данные.

То есть часть команд работает со структурой таблицы, а часть — с её содержимым.

CREATE TABLE

Создаёт таблицу.

sql
CREATE TABLE students (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    age INTEGER,
    group_name TEXT
);

Разберём по-человечески:

  1. CREATE TABLE students — команда "создай таблицу с именем students".
  2. Круглые скобки () содержат описание столбцов таблицы.
  3. id INTEGER PRIMARY KEY AUTOINCREMENT — столбец id, в котором будет число, причём уникальное и увеличивающееся автоматически.
  4. name TEXT NOT NULL — столбец name, в котором хранится текст, и он не может быть пустым.
  5. age INTEGER — столбец для возраста.
  6. group_name TEXT — столбец для названия группы.
  7. ; в конце означает, что команда закончилась.

Иначе говоря, этот запрос не добавляет студентов. Он только создаёт "пустую коробку", в которую потом можно будет складывать записи.

INSERT

Добавляет запись в таблицу.

sql
INSERT INTO students (name, age, group_name)
VALUES ('Анна', 19, 'Вп41');

Разберём по строкам:

  1. INSERT INTO students — команда "добавь новую запись в таблицу students".
  2. (name, age, group_name) — перечисляем, в какие именно столбцы будем записывать значения.
  3. VALUES ('Анна', 19, 'Вп41') — перечисляем сами значения в том же порядке.
  4. 'Анна' попадёт в name.
  5. 19 попадёт в age.
  6. 'Вп41' попадёт в group_name.

В этом запросе мы не указываем id, потому что SQLite создаст его сама.

SELECT

Читает данные из таблицы.

sql
SELECT * FROM students;

Символ * означает "все столбцы". Полезно сразу показать и более точный вариант:

sql
SELECT name, age FROM students;

Разберём первый вариант:

  1. SELECT — команда "покажи данные".
  2. * — показать все столбцы.
  3. FROM students — брать данные из таблицы students.

То есть запрос SELECT * FROM students; означает: "Покажи мне все данные из таблицы students".

Разберём второй вариант:

  1. SELECT name, age — показать только столбцы name и age.
  2. FROM students — брать их из таблицы students.

Такой запрос вернёт не всю строку целиком, а только нужные поля.

WHERE

Фильтрует записи по условию.

sql
SELECT * FROM students
WHERE age >= 18;

Условие WHERE отвечает за фильтрацию. Без него запрос читает или изменяет все записи таблицы. Именно поэтому WHERE особенно важен в UPDATE и DELETE.

Разберём этот запрос:

  1. SELECT * — показать все столбцы.
  2. FROM students — из таблицы students.
  3. WHERE age >= 18 — но только те строки, где возраст больше или равен 18.

То есть база сначала смотрит на все записи, а потом оставляет только подходящие.

Примеры условий:

sql
SELECT * FROM students WHERE age = 19;
SELECT * FROM students WHERE group_name = 'Вп41';
SELECT * FROM students WHERE age > 18;

UPDATE

Изменяет существующие записи.

sql
UPDATE students
SET age = 20
WHERE name = 'Анна';

Разберём по шагам:

  1. UPDATE students — команда "измени данные в таблице students".
  2. SET age = 20 — в подходящих строках поставь возраст 20.
  3. WHERE name = 'Анна' — менять только там, где имя равно Анна.

Этот запрос не создаёт новую запись, а изменяет уже существующую.

DELETE

Удаляет записи.

sql
DELETE FROM students
WHERE name = 'Анна';

Разберём по шагам:

  1. DELETE FROM students — команда "удали записи из таблицы students".
  2. WHERE name = 'Анна' — удалить только те записи, где имя равно Анна.

Этот запрос удаляет строки, которые подходят под условие. Если забыть WHERE, будут удалены все записи таблицы.

Как читать SQL-запрос как алгоритм

Часто проще не заучивать синтаксис, а переводить запрос на обычный язык.

Например:

sql
SELECT name, age FROM students
WHERE age >= 18;

Можно прочитать так:

  1. Возьми таблицу students.
  2. Найди в ней записи, где age >= 18.
  3. Покажи только столбцы name и age.

Такой подход снижает ощущение, что SQL — это набор непонятных команд.

Частые ошибки

  • Писать запрос с ошибкой в названии поля или таблицы.
  • Забывать WHERE в UPDATE или DELETE.
  • Не понимать, какие данные уже есть в таблице перед изменением.
  • Путать создание таблицы и добавление записи в неё.

3.2 Практика ​

Задание 1. Таблица книг

Цель - создать таблицу и выполнить основные SQL-команды.

Шаги:

  1. В SQLiteStudio создайте базу library.db.
  2. Создайте таблицу books с полями id, title, author, year.
  3. Добавьте 2-3 книги через INSERT.
  4. Выполните SELECT * FROM books.
  5. Измените одну запись через UPDATE.
  6. Удалите одну запись через DELETE.
  7. Отдельно объясните словами, что делает каждый запрос.

Пример SQL:

sql
CREATE TABLE books (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    title TEXT NOT NULL,
    author TEXT NOT NULL,
    year INTEGER
);

INSERT INTO books (title, author, year)
VALUES ('1984', 'Оруэлл', 1949);

SELECT * FROM books;

Разбор:

  1. CREATE TABLE books — создаём таблицу books.
  2. id INTEGER PRIMARY KEY AUTOINCREMENT — служебный номер книги, который SQLite будет назначать сама.
  3. title TEXT NOT NULL — название книги, пустым быть не может.
  4. author TEXT NOT NULL — автор книги, тоже не может быть пустым.
  5. year INTEGER — год издания.
  6. INSERT INTO books ... — добавляем новую книгу в таблицу.
  7. VALUES ('1984', 'Оруэлл', 1949) — записываем конкретные данные о книге.
  8. SELECT * FROM books; — просим базу показать все книги, которые сейчас есть в таблице.

Задание 2. Мини-база задач

Цель - закрепить работу с таблицей через интерфейс SQLiteStudio.

Шаги:

  1. Создайте базу tasks.db.
  2. Создайте таблицу tasks с полями id, title, status.
  3. Добавьте несколько записей вручную.
  4. Выполните SELECT * FROM tasks;.
  5. Измените статус одной задачи.
  6. Объясните, какие поля относятся к структуре таблицы, а какие значения относятся к данным.

Как объяснять любой SQL-запрос

Если разбирать запрос пока сложно, удобно использовать один и тот же шаблон:

  1. Что делает команда: создаёт, добавляет, показывает, изменяет или удаляет.
  2. С какой таблицей она работает.
  3. Какие столбцы участвуют.
  4. Есть ли условие WHERE.
  5. Что изменится в базе после выполнения команды.

4. Работа с SQLite из Python ​

4.1 Теория ​

Как подключиться к базе данных

В Python уже есть встроенный модуль sqlite3 для работы с SQLite. Его не нужно устанавливать отдельно: достаточно import sqlite3.

Базовая цепочка действий:

  1. Подключились к базе.
  2. Создали курсор.
  3. Выполнили SQL-команду.
  4. Сохранили изменения.
  5. Закрыли соединение.

Короткая формула: подключение -> выполнение -> сохранение -> закрытие.

Вот базовый код:

python
import sqlite3

# 1. Подключаемся к базе данных (если файла нет, SQLite создаст его)
conn = sqlite3.connect('school.db')

# 2. Создаём курсор
cursor = conn.cursor()

# 3. Выполняем SQL-запрос (например, создаём таблицу)
cursor.execute("""
CREATE TABLE IF NOT EXISTS students (
    id INTEGER PRIMARY KEY,
    name TEXT NOT NULL,
    age INTEGER
)
""")

# 4. Сохраняем изменения
conn.commit()

# 5. Закрываем соединение
conn.close()

Разбор по шагам:

  • import sqlite3: импортируем модуль.
  • sqlite3.connect('school.db'): эта команда создаёт соединение с файлом school.db. Если такого файла нет, он будет создан. Переменная conn — это и есть наше подключение.
  • conn.cursor(): создаёт объект cursor. Через него мы будем отправлять команды в базу данных.
  • cursor.execute(...): выполняет SQL-запрос, который передан в виде строки. Здесь мы создаём таблицу students, если она ещё не существует (IF NOT EXISTS).
  • conn.commit(): подтверждает все изменения, сделанные с момента последнего commit. Без этой команды ничего не сохранится в файле базы данных.
  • conn.close(): закрывает соединение. Это важный шаг, который освобождает файл базы данных.

Очень важная подсказка для новичка

  1. SELECT только читает данные. После него commit() обычно не нужен.
  2. INSERT, UPDATE, DELETE, CREATE TABLE меняют базу. После них нужен commit().
  3. Если забыть close(), файл базы может остаться занятым.

Мини-пример: добавить студента и прочитать таблицу

python
import sqlite3

conn = sqlite3.connect('school.db')
cursor = conn.cursor()

cursor.execute(
    "INSERT INTO students (name, age) VALUES (?, ?)",
    ('Анна', 19)
)

conn.commit()

cursor.execute("SELECT id, name, age FROM students")
rows = cursor.fetchall()

for row in rows:
    print(row)

conn.close()

Разбор этого примера:

  1. Открыли подключение.
  2. Добавили запись через INSERT.
  3. Сохранили изменение (commit).
  4. Выполнили SELECT и получили все строки (fetchall).
  5. Вывели результат.
  6. Закрыли подключение.

Почему лучше писать VALUES (?, ?):

  1. Это безопаснее.
  2. Меньше ошибок с кавычками.
  3. Это правильная практика для параметров в SQL.

Контекстный менеджер with

Чтобы не забывать вызывать conn.commit() и conn.close(), можно использовать конструкцию with. Она делает код чище и безопаснее:

python
import sqlite3

db_name = 'school.db'

with sqlite3.connect(db_name) as conn:
    cursor = conn.cursor()
    cursor.execute("SELECT * FROM students")
    
    # Получаем результат запроса
    all_students = cursor.fetchall()
    print(all_students)

В этом примере:

  • with sqlite3.connect(db_name) as conn: — соединение будет автоматически закрыто после выхода из блока with.
  • Если внутри блока with не возникнет ошибок, изменения будут автоматически сохранены (commit). Если произойдёт ошибка, изменения будут отменены (rollback).
  • cursor.fetchall(): получает все строки, которые вернул SELECT-запрос.

Этот способ является предпочтительным, так как он помогает избежать многих распространённых ошибок.

Частые ошибки и как их избежать

  1. Ошибка: забыли commit() после изменения данных. Результат: программа отработала, но в базе ничего не поменялось.
  2. Ошибка: закрыли соединение слишком рано. Результат: следующие запросы падают с ошибкой.
  3. Ошибка: подставляют значения в SQL через f-строки. Результат: небезопасный и хрупкий код. Правильно: передавать параметры отдельно, через ?.
  4. Ошибка: думают, что курсор работает сам по себе. Важно: cursor существует только внутри активного соединения conn.

Шаблон, который можно использовать почти всегда

  1. import sqlite3
  2. with sqlite3.connect('имя_базы.db') as conn:
  3. cursor = conn.cursor()
  4. cursor.execute("SQL", параметры)
  5. Если это SELECT: fetchone() или fetchall()
  6. Если это изменение: commit() (или положиться на with)

4.2 Практика ​

Задание 1. Первое подключение к базе

Цель - открыть файл базы данных из Python и проверить, что подключение работает.

Шаги:

  1. Создайте файл lesson4_task1.py.
  2. Подключитесь к базе school.db через sqlite3.connect(...).
  3. Создайте курсор.
  4. Выполните запрос SELECT 1;.
  5. Выведите результат на экран.
  6. Закройте соединение.

Ожидаемый результат: программа запускается без ошибок и выводит значение 1.

Задание 2. Чтение данных из таблицы

Цель - получить и вывести записи из таблицы students.

Шаги:

  1. Подключитесь к school.db.
  2. Выполните SELECT id, name, age FROM students;.
  3. Получите все строки через fetchall().
  4. Выведите каждую запись в цикле for.
  5. Отдельно посчитайте, сколько строк вернулось.

Ожидаемый результат: на экран выводится список студентов и количество найденных записей.

Задание 3. Добавление и изменение записи

Цель - отработать INSERT, UPDATE и commit() из Python-кода.

Шаги:

  1. Добавьте в таблицу нового студента через параметризованный запрос с ?.
  2. Сохраните изменения через commit().
  3. Измените возраст этого студента через UPDATE ... WHERE ....
  4. Снова выполните commit().
  5. Выполните SELECT и убедитесь, что данные действительно изменились.

Ожидаемый результат: в таблице есть новая запись, и у неё обновлён возраст.

Задание 4. Мини-CRUD на Python

Цель - связать все основные действия с базой в одном скрипте.

Шаги:

  1. Создайте скрипт lesson4_task4.py.
  2. Реализуйте функцию add_student(name, age).
  3. Реализуйте функцию show_students().
  4. Реализуйте функцию update_student_age(student_id, new_age).
  5. Реализуйте функцию delete_student(student_id).
  6. Внизу файла вызовите функции в таком порядке: добавить -> показать -> изменить -> показать -> удалить -> показать.
  7. Проверьте, что после каждого шага результат соответствует ожидаемому.

Ожидаемый результат: скрипт демонстрирует полный цикл работы с базой (Create, Read, Update, Delete).