SQLite ATTACH DATABASE: синтаксис и примеры

При подключении к базе данных SQLite её имя в соединении обозначается как main, независимо от имени файла на диске. Каждое соединение также имеет доступ к временной базе данных temp, где хранятся временные таблицы и объекты, существующие только во время текущей сессии

Вся рубрика SQLite: уроки, инструменты и примеры

Оператор ATTACH DATABASE расширяет настройки подключения: вы можете подключить сразу несколько файлов баз данных к одному соединению и работать с ними одновременно. Это полезно при объединении данных из разных источников без создания промежуточных копий

Базовый синтаксис оператора:

ATTACH DATABASE file_name AS database_name;

Оператор связывает файл базы данных file_name с текущим соединением под логическим именем (псевдонимом) database_name

Если файл file_name отсутствует, SQLite создаёт новый файл базы данных, и после подключения вы можете обращаться ко всем объектам через префикс database_name. Например, таблица people в базе данных contacts доступна как contacts.people

Несколько дополнительных вариантов использования:

  • Если в качестве имени файла указать :memory:, SQLite создаст новую базу данных в оперативной памяти (in-memory database) и подключит её к текущему соединению. Одновременно можно подключить несколько баз данных в памяти при условии, что каждая из них получит уникальное логическое имя.
  • Если указать пустую строку '', оператор создаст временную файловую базу данных.

Обратите внимание: SQLite автоматически удаляет все временные базы данных и базы данных в памяти при закрытии соединения

Пример: ATTACH DATABASE в SQLite на базе chinook и contacts

Сначала подключитесь к образцу базы данных chinook с помощью команды sqlite3:

sqlite3 c:\sqlite\db\chinook.db

Затем используйте команду .databases, чтобы вывести список всех баз данных в текущем соединении:

sqlite> .databases

SQLite вернёт следующий результат:

seq name file
--- --------------- ----------------------------------------------------------
0 main c:\sqlite\db\chinook.db

Используйте оператор ATTACH DATABASE, чтобы создать новую базу данных с именем contacts и подключить её к текущему соединению:

sqlite> attach database 'c:\sqlite\db\contacts.db' as contacts;

После этого снова выполните команду .databases, чтобы убедиться, что подключение прошло успешно:

SQLite вернёт уже две базы данных:

seq name file
--- --------------- ----------------------------------------------------------
0 main c:\sqlite\db\chinook.db
2 contacts c:\sqlite\db\contacts.db

По этой теме полезно отдельно посмотреть EXPLAIN QUERY PLAN: план выполнения SQL-запроса в SQLite, чтобы расширить контекст и сравнить подходы

По этой теме полезно отдельно посмотреть Создание Flutter-приложения с SQLite, BLoC и Streams, чтобы расширить контекст и сравнить подходы

Перенос данных между базами данных SQLite через ATTACH

Создадим таблицу people в базе данных contacts и заполним её данными из таблицы customers основной базы данных:

sqlite> CREATE TABLE contacts.people ( first_name text, last_name text
);

sqlite> INSERT INTO contacts.people SELECT firstName, lastName FROM customers;

Обратите внимание на соглашение об именовании: таблица people в базе данных contacts адресуется как contacts.people. Именно так SQLite различает объекты разных подключённых баз данных в рамках одного соединения

Наконец, выполните запрос данных из таблицы people в базе данных contacts:

SELECT * FROM contacts.people;

Я рекомендую всегда указывать префикс базы данных при работе с несколькими подключёнными файлами — это исключает путаницу и делает запросы читаемыми

Типичные ошибки при работе с ATTACH DATABASE

При использовании оператора ATTACH DATABASE стоит учитывать несколько распространённых ситуаций, которые могут привести к неожиданному поведению

Конфликт логических имён. Если вы попытаетесь подключить базу данных под именем, которое уже используется в текущем соединении, SQLite вернёт ошибку. Убедитесь, что псевдоним database_name уникален в рамках сессии

Использование зарезервированных имён. Имена main и temp зарезервированы SQLite. Нельзя использовать их в качестве database_name при вызове ATTACH DATABASE

Базы данных, созданные с именем :memory:, существуют только в оперативной памяти и уничтожаются при закрытии соединения. Для сохранения данных используйте реальный путь к файлу

При работе с несколькими подключёнными базами данных SQLite разрешает неоднозначные имена таблиц по определённым правилам. Всегда указывайте префикс database_name.table_name — это поможет избежать неясностей

Права доступа к файлу. Если файл базы данных защищён от записи или недоступен, ATTACH DATABASE может завершиться ошибкой. Проверьте права доступа к файлу перед подключением

Когда использовать ATTACH DATABASE

Оператор ATTACH DATABASE особенно полезен в следующих сценариях:

  • Объединение данных из нескольких файлов. Вы можете выполнять JOIN-запросы между таблицами из разных файлов баз данных без необходимости копировать данные.
  • Миграция данных. Удобно переносить данные из одной базы данных в другую в рамках одного SQL-скрипта.
  • Изолированное тестирование. Подключение базы данных в памяти (:memory:) позволяет создавать временные структуры для тестов, не затрагивая основной файл.
  • Модульная архитектура приложения. Разные части приложения могут хранить данные в отдельных файлах, которые при необходимости объединяются через ATTACH DATABASE.

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

Ответы на эти вопросы могут быть для вас полезными

Можно ли подключить несколько баз данных одновременно? Да. SQLite позволяет подключать несколько баз данных к одному соединению. Каждая из них должна получить уникальное логическое имя. Количество одновременно подключённых баз данных ограничено параметром SQLITE_MAX_ATTACHED, который по умолчанию равен 10

Что произойдёт, если файл базы данных не существует? SQLite автоматически создаст новый пустой файл базы данных по указанному пути. Это поведение аналогично тому, что происходит при первом вызове sqlite3 с несуществующим файлом

Как отключить подключённую базу данных? Используйте оператор DETACH DATABASE database_name. Например: DETACH DATABASE contacts;. После этого объекты базы данных contacts станут недоступны в текущем соединении

Можно ли использовать транзакции, охватывающие несколько подключённых баз данных? SQLite поддерживает транзакции, затрагивающие несколько подключённых баз данных, однако атомарность между разными файлами не гарантируется в полной мере. Для критически важных операций рекомендуется использовать WAL-режим и тщательно тестировать поведение при сбоях

Сохраняется ли подключение базы данных между сессиями? Нет. Оператор ATTACH DATABASE действует только в рамках текущего соединения. При следующем запуске sqlite3 или новом подключении из кода необходимо снова выполнить ATTACH DATABASE

Оцените статью
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x