SQL: создаём, читаем и изменяем данные
Один язык — и создание таблиц, и чтение, и изменение, и удаление данных.
SQL (Structured Query Language — язык структурированных запросов) — язык определения структуры данных и выполнения запросов к реляционной базе данных: им создают таблицы, читают, добавляют, изменяют и удаляют строки. У SQL есть общий стандарт, но у каждой конкретной системы (SQLite, PostgreSQL, MySQL) — свои расширения и особенности поверх него, поэтому говорят не о «разных языках SQL», а о разных диалектах одного языка. Примеры на этой странице выполняются в SQLite (раздел 22.23).
CREATE TABLE — описываем структуру
CREATE TABLE tasks (
id INTEGER PRIMARY KEY,
title TEXT NOT NULL,
done INTEGER NOT NULL DEFAULT 0
);
NOT NULL запрещает записывать в столбец специальное SQL-значение NULL («значение неизвестно / отсутствует»). Пустая строка '' — это по-прежнему допустимое значение типа TEXT, и NOT NULL её не отклонит. Если приложению нужно запретить именно пустой (или состоящий из пробелов) заголовок задачи, для этого нужна отдельная проверка — на стороне приложения (раздел 22.31) или явное ограничение CHECK, как показывает раздел 22.29.DEFAULT 0 задаёт значение по умолчанию, если его не указали
явно.
Четыре операции CRUD
| Действие | SQL | Что делает |
|---|---|---|
| Create | INSERT | Добавить новую строку |
| Read | SELECT | Прочитать одну или несколько строк |
| Update | UPDATE | Изменить существующую строку |
| Delete | DELETE | Удалить строку |
INSERT INTO tasks (title) VALUES ('Купить хлеб');
SELECT id, title, done FROM tasks WHERE done = 0 ORDER BY id LIMIT 10;
WHERE оставляет только подходящие строки,
ORDER BY задаёт порядок, LIMIT
ограничивает количество результатов.
UPDATE tasks SET done = 1 WHERE id = 1;
DELETE FROM tasks WHERE id = 1;
SQL из Python: модуль sqlite3
import sqlite3
baza = sqlite3.connect("zadachi.db")
baza.execute(
"INSERT INTO tasks (title) VALUES (?)",
("Купить хлеб",),
)
baza.commit()
stroki = baza.execute("SELECT id, title, done FROM tasks").fetchall()
for stroka in stroki:
print(stroka)
? в SQL-строке — это параметризованный запрос: значение подставляет сам модуль sqlite3, безопасно, отдельно от текста запроса. Если вместо этого собрать запрос через f-строку с пользовательским вводом внутри, это открывает путь к SQL-инъекции — что именно может пойти не так и почему параметризация обязательна, а не желательна, показывает раздел 22.32.