SQLite PHPPythonSQLiteLinuxWindows

SQLite: SQLite не применяет PRAGMA foreign_keys для нового подключения

  • Обновлено
  • Чтение ≈ 3 минуты

Краткий ответ

SQLite контролирует внешние ключи отдельно для каждого нового подключения, если PRAGMA foreign_keys включена до начала транзакции. Настройка одного sqlite3-клиента не распространяется на все соединения PHP/Python и не меняет уже начатую транзакцию.

В этой статье
  1. Симптом и границы применимости
  2. Как отличить возможные причины
  3. Пошаговая диагностика и безопасное исправление
  4. Как проверить, что проблема устранена
  5. Если исправление не помогло

#Симптом и границы применимости

SQLite контролирует внешние ключи отдельно для каждого нового подключения, если PRAGMA foreign_keys включена до начала транзакции. Настройка одного sqlite3-клиента не распространяется на все соединения PHP/Python и не меняет уже начатую транзакцию.

#Как отличить возможные причины

Возможная причинаКак узнатьЧто делать
Новая сессия сбрасывает настройкуPRAGMA foreign_keys — настройка соединения, а не постоянное свойство файла.sqlite3 показывает ON, PHP — OFFУстановить при создании соединения
Команда внутри транзакцииИзменение PRAGMA foreign_keys во время BEGIN не действует.Внутри транзакции остается 0Перенести до BEGIN
Есть старые нарушенные ссылкиВключение контроля не исправляет исторические сиротские строки.PRAGMA foreign_key_check возвращает строкиСогласовать исправление данных

#Пошаговая диагностика и безопасное исправление

  1. 1. Уточните, где создаётся соединениеНайдите файл PHP или Python, в котором открывается SQLite, и все места повторного открытия базы, включая фоновые задачи. Не считайте установку PRAGMA из консоли постоянной настройкой сервера.
  1. 2. Проверьте значение на новом соединенииВ терминале откройте sqlite3 именно для нужного файла тестовой базы. Проверьте PRAGMA foreign_keys сразу после открытия; 0 означает, что на данном соединении контроль не включён.
    Linux · Терминал (Bash)Команда
    Терминал с SQLite CLI; чтение. ./test.db — только существующая копия базы, не открывайте неизвестный путь (он может создать пустой файл).
    sqlite3 ./test.db "PRAGMA foreign_keys;"
  1. 3. Проверяйте ограничения на тестовой копииЗапустите foreign_key_check: он находит уже существующие нарушения, но не исправляет их. Результат без строк — ожидаемое состояние здоровой базы с проверяемыми ограничениями.
  2. В sqlite3 внутри тестовой базы; чтение, возможна нагрузка на большую базу
    SQLКоманда
    В sqlite3 внутри тестовой базы; чтение, возможна нагрузка на большую базу.
    PRAGMA foreign_key_check;
  1. 4. Включите проверку до первой транзакцииВ коде при каждом новом подключении выполняйте PRAGMA foreign_keys=ON до BEGIN и перед любыми подготовленными запросами, зависящими от настройки. Затем сразу запросите текущее значение и убедитесь, что оно 1.
  1. 5. Добавьте установку в PHP PDO на тестеЕсли сайт использует PDO_SQLITE, выполните PRAGMA после new PDO и до начала транзакции. Пример не подменяет реальный путь и не должен открывать производственную базу из тестового сценария.
  2. Дополнительная команда по теме
    PHPКоманда
    Фрагмент PHP только для тестового файла; ожидается int(1) либо строка «1» в зависимости от драйвера.
    $db = new PDO('sqlite:/absolute/path/to/test.db');
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $db->exec('PRAGMA foreign_keys = ON');
    var_dump($db->query('PRAGMA foreign_keys')->fetchColumn());
  1. 6. Отдельно испытайте соединения из пулаЗапустите два независимых подключения и проверьте PRAGMA foreign_keys в каждом, затем проведите безопасный INSERT с некорректной ссылкой в откатываемой тестовой транзакции. Ожидается отказ FOREIGN KEY constraint failed.
  1. 7. Разберите ошибки старых данных до выпускаЕсли foreign_key_check выявил сироты, составьте список и согласуйте восстановление корректных родительских записей или удаление по бизнес-правилам. Не отключайте проверку ради успешного завершения миграции.
  1. 8. Проверьте поведение после перезапуска процессаПерезапустите только тестовое приложение, создайте свежее соединение и убедитесь, что PRAGMA снова равна 1. Автотест должен проверять это каждый раз при развёртывании.

#Как проверить, что проблема устранена

Каждое новое тестовое подключение показывает PRAGMA foreign_keys = 1; допустимые ссылки проходят, недопустимые завершаются ошибкой целостности.

#Если исправление не помогло

Если PRAGMA остаётся 0, проверьте, не выполняется ли она внутри BEGIN и не открывает ли код другую базу. На очень старых сборках SQLite поддержка FK может быть отключена при компиляции.

Так эту ошибку тоже называют

Источники и обновления

Последнее обновление статьи: 2 ноября 2026. Версии программ и интерфейсы меняются — если шаги не совпадают с вашей версией, сверяйтесь с документацией производителя.