SQL с нуля через Python: первая база SQLite и таблица
Первая настоящая база данных без установки серверов: import sqlite3, курсор, CREATE TABLE и первые строки — всё исполняется прямо на странице.
Редакция Питоники
Ты уже умеешь хранить данные в списках и словарях, но закрыл программу — и всё исчезло. Записал в файл — а найти «все книги дороже пятисот» уже требует ручного перебора. Именно эту скуку убирают базы данных, а язык, на котором с ними разговаривают, называется SQL. Хороший новостной фон: он не менялся по сути лет тридцать и выучен один раз — работает везде, от мобильных приложений до аналитических отделов.
У этого раздела есть суперспособность: SQLite входит в стандартную библиотеку Python, поэтому каждая таблица в код-блоках ниже — настоящая. Жмёшь «Запустить» — в браузере поднимается живая база, создаётся таблица, вставляются строки, и SELECT возвращает данные. Никаких имитаций и никаких установок.
Что такое база данных и SQL на пальцах?
База данных — это умный файл: движок хранит строки так, чтобы находить нужные за миллисекунды даже среди миллионов записей. Внутри у неё индексы, журнал изменений и планировщик запросов, но снаружи всё это спрятано: ты пишешь вопрос на SQL — получаешь строки. SQL (Structured Query Language, язык структурированных запросов) — декларативный язык: ты описываешь, ЧТО хочешь получить, а движок сам решает, КАК это достать.
Первое знакомство обычно проходит через аналогию с Excel, и она правда помогает: таблицы, строки, колонки. Но аналогия врёт в трёх местах, и честнее знать об этом сразу.
- Типы колонок честные: в колонке year лежат только целые числа, а не «что ввёл пользователь, лишь бы влезло».
- Условия встроены в язык: «покажи строки, где цена между 400 и 700» — одна строчка SQL, а не ручной обход ячеек.
- Миллионы строк — норма: Excel начинает задыхаться на сотнях тысяч, база с индексом находит строку среди миллионов так же быстро.
Дальше по курсу ты встретишь и вторую половину SQL — агрегаты и JOIN (уроки 6 и 7 раздела про SQL), но фундамент у всего один: создать таблицу, вставить строки, прочитать их. Этим и займёмся.
Чем SQLite отличается от MySQL?
Базы данных бывают двух архитектур. Серверные — MySQL, PostgreSQL — это отдельные программы, которые живут на машине (обычно другой), слушают порт и пускают к себе по логину и паролю. Встраиваемые — SQLite — это библиотека: весь движок лежит внутри твоего процесса, а база — обычный файл рядом с кодом. Ни установки, ни порта, ни пароля.
# Серверная база (MySQL) требует адрес, логин и пароль:
# import mysql.connector
# conn = mysql.connector.connect(
# host="localhost", # где живёт сервер
# user="root", # кто подключается
# password="s3cret", # пароль
# database="library", # какая база
# )
# SQLite: весь сервер уже внутри Python, нужен только путь к файлу:
import sqlite3
conn = sqlite3.connect("library.db")
Из-за простоты SQLite — самая массовая база в мире: она живёт в каждом смартфоне (Android и iOS), в браузерах, в мессенджерах. Для обучения, прототипов, настольных приложений и сайтов с небольшой нагрузкой её хватает с запасом. А язык SQL в ней тот же: запросы из этого курса работают и в PostgreSQL, отличия — в мелочах, и мы будем их отмечать.
| Свойство | SQLite | MySQL / PostgreSQL |
|---|---|---|
| Установка | уже встроена в Python | отдельный сервер |
| Где лежат данные | один файл рядом с кодом | на сервере, доступ по сети |
| Подключение | sqlite3.connect(путь) | host, порт, логин, пароль |
| Параллельные писатели | один в момент времени | много, с блокировками строк |
| Для чего | учёба, приложения, встраивание | сервисы с большой нагрузкой |
Что делает import sqlite3?
Модуль sqlite3 входит в стандартную библиотеку — pip не нужен, ничего качать не надо. Он даёт два главных класса: Connection (соединение с базой — файлом или памятью) и Cursor (рабочая рука, через которую уходят запросы и приходят строки). Посмотрим на них вживую.
import sqlite3
conn = sqlite3.connect(":memory:")
print(type(conn))
cur = conn.cursor()
print(type(cur))
conn.close()
<class 'sqlite3.Connection'> <class 'sqlite3.Cursor'>
Разбираем по строкам. sqlite3.connect(":memory:") открывает базу — строка ":memory:" означает «не в файле, а в оперативной памяти»: база живёт, пока открыто соединение, и исчезает вместе с ним. Для учёбы это идеальный вариант — каждый запуск блока начинается с чистого листа. conn.cursor() создаёт курсор, а conn.close() закрывает соединение: привычка закрывать его явно пригодится, когда база станет файлом на диске.
Что делает cursor и зачем он нужен?
Курсор — посредник между Python и SQL: метод execute() отправляет запрос движку, а методы fetchone(), fetchall() и fetchmany() забирают результаты. Можно представлять его указателем на текущую строку выдачи: запрос наполняет список строк, а fetch-методы читают его, сдвигая указатель. Забавная деталь, которая поначалу сбивает с толку: execute() возвращает не данные, а сам курсор — поэтому один и тот же объект.
import sqlite3
conn = sqlite3.connect(":memory:")
cur = conn.cursor()
# execute возвращает не результат, а тот же курсор:
print(cur.execute("SELECT 40 + 2") is cur)
# поэтому fetchone можно вызвать сразу через точку:
print(cur.execute("SELECT 7 * 6").fetchone())
conn.close()
True (42,)
Как создать первую таблицу: CREATE TABLE?
Таблица в базе — как таблица в Excel, только с контрактом: у каждой колонки есть имя и тип, и двигаться колонки не могут. Создание таблицы — тоже SQL-запрос, CREATE TABLE. После него таблица существует — убедимся, спросив служебный каталог sqlite_master, где SQLite хранит список всех таблиц базы.
import sqlite3
conn = sqlite3.connect(":memory:")
cur = conn.cursor()
cur.execute("""
CREATE TABLE books (
id INTEGER PRIMARY KEY,
title TEXT,
author TEXT,
year INTEGER
)
""")
# sqlite_master - служебный каталог: какие таблицы есть в базе
cur.execute("SELECT name FROM sqlite_master WHERE type = 'table'")
print(cur.fetchall())
conn.close()
[('books',)]Читаем схему как контракт. id INTEGER PRIMARY KEY — уникальный номер каждой строки: SQLite сама будет присваивать 1, 2, 3… (подробно — в уроке 2 про типы и схему). title TEXT и author TEXT — строки, year INTEGER — целое. Многострочная строка в тройных кавычках — просто способ красиво оформить SQL; движку всё равно, в одну строку запрос или в четыре.
Как вставить и прочитать первые строки?
Пустая таблица — это только схема. Наполним её командой INSERT INTO ... VALUES и прочитаем командой SELECT: классический минимальный цикл жизни данных. Пока вставляем явно и id, и все значения — в третьем уроке научимся передавать данные через параметры, как это делают в настоящем коде.
import sqlite3
conn = sqlite3.connect(":memory:")
cur = conn.cursor()
cur.execute("""
CREATE TABLE books (
id INTEGER PRIMARY KEY,
title TEXT,
author TEXT,
year INTEGER
)
""")
cur.execute("INSERT INTO books VALUES (1, 'Мастер и Маргарита', 'Булгаков', 1967)")
cur.execute("INSERT INTO books VALUES (2, 'Преступление и наказание', 'Достоевский', 1866)")
cur.execute("SELECT * FROM books")
for row in cur.fetchall():
print(row)
conn.close()
(1, 'Мастер и Маргарита', 'Булгаков', 1967) (2, 'Преступление и наказание', 'Достоевский', 1866)
SELECT * FROM books читается по-русски так: «выбери все колонки (*) из таблицы books». Каждая строка приходит в Python кортежем — значения по порядку колонок, как договаривалась схема. С кортежами ты уже умеешь: индексируй, распаковывай, считай длину.
import sqlite3
conn = sqlite3.connect(":memory:")
cur = conn.cursor()
cur.execute("CREATE TABLE books (id INTEGER PRIMARY KEY, title TEXT, author TEXT, year INTEGER)")
cur.execute("INSERT INTO books VALUES (1, 'Мастер и Маргарита', 'Булгаков', 1967)")
cur.execute("INSERT INTO books VALUES (2, 'Преступление и наказание', 'Достоевский', 1866)")
cur.execute("SELECT * FROM books")
rows = cur.fetchall()
print(rows) # список кортежей
print(len(rows)) # сколько строк вернул запрос
print(rows[0]) # первая строка - кортеж
print(rows[0][1]) # заголовок первой книги
conn.close()
[(1, 'Мастер и Маргарита', 'Булгаков', 1967), (2, 'Преступление и наказание', 'Достоевский', 1866)] 2 (1, 'Мастер и Маргарита', 'Булгаков', 1967) Мастер и Маргарита
Что значит :memory: и при чём тут файл?
Мы всё время писали connect(":memory:") — пора показать, что база SQLite это в первую очередь файл. Один вызов connect с путём — и на диске появляется библиотека: та же схема, те же запросы. Этот блок тоже настоящий: он создаёт файл, а в конце убирает его за собой.
import os
import sqlite3
DB = "library.db"
if os.path.exists(DB):
os.remove(DB) # начинаем с чистого листа
conn = sqlite3.connect(DB) # база - файл рядом со скриптом
cur = conn.cursor()
cur.execute("CREATE TABLE books (id INTEGER PRIMARY KEY, title TEXT)")
cur.execute("INSERT INTO books (title) VALUES ('Евгений Онегин')")
conn.commit() # сохраняем изменения в файл
conn.close()
print("Файл базы:", os.path.exists(DB))
os.remove(DB) # убираем за собой
print("После удаления:", os.path.exists(DB))
Файл базы: True После удаления: False
Здесь появился новый метод — conn.commit(): он фиксирует изменения в файле. В базах в памяти от него ничего не видно, а вот с файлом без него данные не сохранятся — этому посвящён отдельный питфолл в уроке 3 про INSERT и SELECT. Кстати, файл library.db можно открыть любой SQLite-утилитой — внутри обычная база, никакого секретного формата.
Как выглядит код с базой в настоящем проекте?
Учебные блоки держат всё в одном месте, а в реальном проекте соединение открывают один раз, обкладывают его with и хранят схему отдельным модулем. Вот честный продакшн-фрагмент — он не запускается на странице, потому что пишет в файл твоего компьютера, но именно так выглядит работа с sqlite3 после этого курса.
import sqlite3
def get_connection(path):
conn = sqlite3.connect(path)
conn.execute("PRAGMA foreign_keys = ON") # будем проверять связи - урок 7
return conn
conn = get_connection("app.db")
with conn: # with сделает commit (или откат)
conn.execute("""
CREATE TABLE IF NOT EXISTS logs (
id INTEGER PRIMARY KEY,
text TEXT
)
""")
conn.execute("INSERT INTO logs (text) VALUES ('старт приложения')")
conn.close()
Новое здесь ровно два слова. IF NOT EXISTS — «не ругайся, если таблица уже создана»: при каждом старте программы схема проверяется, а не падает. with conn: — контекстный менеджер, который по выходу из блока делает commit (или откат при ошибке); закрывать соединение он не умеет, поэтому дальше стоит явный close(). Полный разбор транзакций — в девятом уроке.
Собираем всё вместе: мини-программа
Закрепим связку connect — cursor — CREATE — INSERT — SELECT в одной маленькой программе: музыкальный плейлист вместо книжной полки. Это последний блок урока с новым содержанием, дальше — проверь себя.
import sqlite3
conn = sqlite3.connect(":memory:")
cur = conn.cursor()
cur.execute("CREATE TABLE tracks (id INTEGER PRIMARY KEY, title TEXT, minutes INTEGER)")
cur.execute("INSERT INTO tracks (title, minutes) VALUES ('Бустер', 4)")
cur.execute("INSERT INTO tracks (title, minutes) VALUES ('Прогулка по воде', 5)")
cur.execute("INSERT INTO tracks (title, minutes) VALUES ('Гуд-бай, Америка', 6)")
cur.execute("SELECT title, minutes FROM tracks")
for row in cur.fetchall():
print(row)
cur.execute("SELECT COUNT(*) FROM tracks")
print("Всего треков:", cur.fetchone()[0])
conn.close()
('Бустер', 4)
('Прогулка по воде', 5)
('Гуд-бай, Америка', 6)
Всего треков: 3SELECT COUNT(*) FROM tracks — первое знакомство с агрегатной функцией: она считает строки и возвращает одну строку с одним числом. Разбор COUNT, SUM и AVG с группировкой — шестой урок курса, а пока просто запомни приём «посчитать, сколько всего».
Что дальше
Ты создал первую базу, понял роли Connection и Cursor, создал таблицу через CREATE TABLE и прошёл полный цикл: вставить строки — прочитать — посчитать. Следующий шаг — научиться проектировать схемы по-взрослому: в уроке 2 разбираем пять типов SQLite, ограничения NOT NULL, UNIQUE и DEFAULT и команду ALTER TABLE. А если хочется сразу увидеть, зачем всё это аналитику, загляни в первый урок Pandas: там данные уже лежат готовыми таблицами, и выученный SQL прицепится к ним через pd.read_sql.
SQL — самый долговечный навык программиста: язык почти не менялся за сорок лет, а нужен он аналитикам, бэкендерам и тестировщикам одинаково.
Сначала предскажи ответ в голове — это главный навык программиста.
import sqlite3
conn = sqlite3.connect(":memory:")
cur = conn.cursor()
print(cur.execute("SELECT 10 - 3").fetchone())
import sqlite3
conn = sqlite3.connect(":memory:")
cur = conn.cursor()
cur.execute("CREATE TABLE t (id INTEGER PRIMARY KEY, name TEXT)")
cur.execute("INSERT INTO t (name) VALUES ('альфа')")
cur.execute("INSERT INTO t (name) VALUES ('бета')")
cur.execute("SELECT id, name FROM t")
rows = cur.fetchall()
print(len(rows))
print(rows[1][0])
import sqlite3
conn = sqlite3.connect(":memory:")
cur = conn.cursor()
cur.execute("CREATE TABLE t (x INTEGER)")
cur.execute("SELECT * FROM t")
print(cur.fetchall())
1. Что означает строка ":memory:" в вызове sqlite3.connect(":memory:")?
2. Как правильно получить строки после cur.execute("SELECT * FROM books")?
3. Чем SQLite отличается от MySQL?
4. Что выведет print(cur.execute("SELECT 7 * 6")) без вызова fetch-метода?
5. Где SQLite хранит список всех таблиц базы?
Создайте в памяти базу и таблицу films (id INTEGER PRIMARY KEY, title TEXT, director TEXT, year INTEGER). Вставьте два фильма: «Ирония судьбы» Рязанова 1975 года и «Кин-дза-дза!» Данелии 1986 года. Выведите все строки таблицы по одной — формат совпадает с заготовкой.
Что такое SQLite и почему она уже есть в Python?
SQLite — встраиваемая база данных: весь движок собран как библиотека, которую встраивают в программу, поэтому в стандартный модуль sqlite3 она входит «из коробки» и не требует установки. База хранится в одном файле (или в памяти при ":memory:"), а язык запросов — обычный SQL, тот же, что в MySQL и PostgreSQL.
Нужно ли устанавливать сервер баз данных, чтобы начать?
Нет. Для этого курса не нужны ни MySQL, ни PostgreSQL: SQLite работает внутри Python, а на этой странице — внутри браузера через Pyodide. Каждый код-блок сам открывает базу, создаёт таблицу и выполняет запросы, так что старт вообще без установки чего-либо.
Что значит ":memory:" в sqlite3.connect?
Специальное имя, которое просит держать базу в оперативной памяти, а не в файле. База живёт, пока открыто соединение, и исчезает при close() — идеально для учёбы и тестов: каждый запуск начинается с чистого состояния. Для постоянного хранения передайте путь: sqlite3.connect("mydata.db").
Чем SQL отличается от Python?
Python — универсальный язык программирования: циклы, функции, классы. SQL — специализированный декларативный язык запросов к данным: вы описываете, какие строки нужны, а движок сам выбирает способ их достать. Они не конкуренты, а пара: Python готовит данные и логику, SQL быстро ищет и считает в базе.
Понравился урок? Сошлитесь на него
«База данных — это умный файл: движок хранит строки так, чтобы находить нужные за миллисекунды даже среди миллионов записей.»
Скопируйте готовую ссылку в формате HTML, Markdown или чистый адрес и вставьте в статью на Habr, VC, Telegram-канал или свой блог — так о проекте узнают новые читатели.
Что читать дальше
sqlite3 · Урок 2
Типы данных SQLite и CREATE TABLE: строим схему базы
Пять типов SQLite, ограничения NOT NULL, UNIQUE и DEFAULT, PRIMARY KEY с автонумерацией и ALTER TABLE — проектируем схему таблицы товаров по-взрослому.
Pandas · Урок 1
Что такое Pandas и как установить через pip: первые Series и DataFrame
Первая таблица DataFrame в библиотеке pandas, умный столбец Series и быстрый осмотр данных через head, info и describe — старт сквозного анализа данных интернет-магазина.
Похожие уроки по темам
Подобраны автоматически по пересечению тем и ключевых слов.
NumPy · Урок 1
Что такое NumPy и как установить через pip: первый массив ndarray
Первый массив ndarray: создаём, сравниваем со списком, разбираем dtype и shape — и ускоряем сумму миллиона чисел примерно в сто раз.
numpy для начинающихучебник numpy
aiogram · Урок 6
База данных в телеграм-боте: SQLite от первого лица
Даём боту настоящую память: таблица пользователей с chat_id, запись через INSERT OR IGNORE, чтение по chat_id и параметр ? против SQL-инъекций.
sqlite телеграм боттелеграм бот база данных
sqlite3 · Урок 9
Транзакции и индексы в SQLite: целостность и скорость
Перевод денег не бывает наполовину: либо обе операции, либо ни одной. Разбираем транзакции и индексы SQLite — кнопку «отменить» и оглавление для таблиц.
sqlite транзакцииcreate index sqlite