Что выбрать
SQLite или PostgreSQL для бота или небольшого сайта
Коротко
Для Telegram-бота или небольшого сайта, где с базой работает одно приложение, обычно хватает SQLite: это один файл, отдельный сервер базы не нужен. PostgreSQL стоит выбрать, когда в базу одновременно пишут несколько процессов или сервисов, когда нужен доступ к базе из других программ или когда данных и пользователей становится много. Главное правило на хостинге для SQLite — файл базы должен лежать в постоянном хранилище, иначе он вернётся к исходному виду при следующей публикации. PostgreSQL поднимают отдельным сервисом рядом с приложением или берут внешнюю управляемую базу.
- SQLite хранит всю базу в одном файле и работает внутри приложения, без отдельного сервера базы данных.
- В SQLite в один момент времени пишет только один процесс; режим WAL позволяет читать параллельно с записью.
- PostgreSQL — отдельный сервер базы данных, к которому могут одновременно подключаться несколько приложений и сервисов.
- Резервная копия SQLite — это копия файла базы, а для PostgreSQL обычно используют утилиту pg_dump.
- Перенести данные из SQLite в PostgreSQL можно утилитой pgloader, а ORM вроде SQLAlchemy или Django ORM упрощают сам переход.
Бот запоминает пользователей, сайт хранит заявки, и в какой-то момент возникает вопрос: где держать данные. В уроках по ботам почти всегда SQLite, в статьях про «настоящую» разработку — PostgreSQL, и кажется, что SQLite — это что-то для учёбы. На деле это не так: SQLite прекрасно работает в рабочих проектах, если понимать её ограничения.
Разница между ними не в «серьёзности», а в устройстве. SQLite — это библиотека, которая хранит всю базу в одном файле и работает прямо внутри вашего приложения. PostgreSQL — отдельная программа-сервер, к которой приложения подключаются по сети. Ниже — как выбрать и как не потерять данные после публикации.
| Критерий | SQLite | PostgreSQL |
|---|---|---|
| Установка | ничего ставить не нужно, модуль sqlite3 встроен в Python | нужен отдельный сервер базы данных |
| Где хранятся данные | один файл рядом с приложением | на сервере базы, в его собственных файлах |
| Одновременная запись | один писатель за раз, остальные ждут | много одновременных записей из разных процессов |
| Доступ из нескольких сервисов | неудобно: файл должен быть виден всем | да, по сети через строку подключения |
| Объём | спокойно справляется с гигабайтами данных небольшого проекта | рассчитан на большие объёмы и сложные запросы |
| Резервная копия | скопировать файл базы | утилита pg_dump или средства провайдера |
| Когда переходить | пока пишет одно приложение и всё работает быстро | несколько сервисов, частые ошибки database is locked, рост нагрузки |
Начните с SQLite, если с базой работает одно приложение#
Для бота на одном процессе, небольшого сайта, панели или парсера SQLite — самый простой выбор: модуль sqlite3 встроен в Python, отдельный сервер не нужен, база — один файл. Она быстро отвечает на запросы небольшого проекта и выдерживает тысячи пользователей, если запись не идёт из многих мест одновременно. Включите режим WAL одной командой PRAGMA journal_mode=WAL: так чтение не будет ждать записи.
Выберите PostgreSQL, если пишут несколько процессов или сервисов#
PostgreSQL нужен, когда с базой работает больше одного приложения: например, бот и сайт-админка, или несколько копий сайта, или фоновые задачи рядом с основным процессом. Ещё один признак — ошибки database is locked в SQLite: значит, запись идёт из нескольких мест и ей тесно. PostgreSQL также удобнее, если нужен доступ к базе из внешних программ, сложные запросы или строгие права доступа.
Храните файл SQLite в постоянной папке#
На хостинге проект при каждой публикации собирается заново из загруженных файлов, поэтому база, записанная рядом с кодом, вернётся к исходному виду. Файл SQLite должен лежать в постоянном хранилище, а путь к нему лучше задавать переменной окружения, а не строкой в коде. Тогда на компьютере база лежит в папке проекта, а на сервере — там, где она переживёт обновления. Не загружайте вместе с кодом свою локальную базу с тестовыми данными, если не хотите, чтобы она перезаписала рабочую.
Поднимите PostgreSQL рядом с приложением или подключите внешнюю базу#
Есть два пути. Первый — описать базу отдельным сервисом в docker-compose рядом с приложением и подключить ей именованный том, чтобы данные переживали обновления. Второй — взять управляемую базу PostgreSQL у облачного провайдера, например Supabase или Neon, и передать приложению строку подключения как секрет. Первый путь держит всё в одном проекте, второй снимает с вас резервные копии и обновления самой базы.
Настройте резервные копии с первого дня#
Для SQLite копия — это файл базы: его можно скачать, но если включён режим WAL, рядом лежат файлы с окончаниями -wal и -shm, и их нужно забирать вместе или делать копию командой .backup. Для PostgreSQL используют pg_dump, который выгружает базу в один файл. Сделайте копию перед каждым крупным изменением структуры базы и храните её не только на том же сервере.
Переходите на PostgreSQL, когда появятся признаки#
Не стоит переезжать заранее: если SQLite справляется, лишний сервер — это лишняя сложность. Признаки, что пора: ошибки database is locked, второе приложение, которому нужны те же данные, заметное замедление запросов. Сам переезд проще, если код работает с базой через ORM: тогда меняется строка подключения, а данные переносятся утилитой pgloader или выгрузкой и загрузкой.
Для большинства ботов и небольших сайтов SQLite — разумный выбор, а не временная мера: переходить на PostgreSQL имеет смысл, когда в базу начинают писать несколько процессов. В Netrun SQLite кладут в постоянную папку /data: её содержимое переживает обновление кода и перезапуск, а файл базы можно посмотреть, скачать и загрузить обратно на вкладке «Данные». PostgreSQL поднимают сервисом в docker-compose с именованным томом — у таких проектов хранилище задаётся томами, а папки /data нет, и память тарифа делится между сервисами, — или подключают внешнюю базу. Управляемой базы данных как отдельной услуги у Netrun нет. Попробовать Netrun.
Частые вопросы
Подойдёт ли SQLite для Telegram-бота с тысячами пользователей?
Да, если бот работает одним процессом. Запросы бота короткие, и SQLite успевает их обрабатывать с большим запасом. Ограничение не в количестве пользователей, а в том, сколько разных процессов пишет в базу одновременно.
Что значит ошибка database is locked?
Это значит, что один процесс пишет в базу, а другой в это время тоже пытается писать и не дождался своей очереди. Помогает режим WAL, короткие транзакции и запись из одного места. Если ошибка повторяется регулярно, это признак, что проекту пора на PostgreSQL.
Почему база SQLite пропала после обновления кода?
Потому что файл базы лежал рядом с кодом, а проект при публикации собирается заново из загруженных файлов. Перенесите файл в постоянное хранилище и задайте путь к нему переменной окружения. После этого база будет переживать обновления.
Можно ли поставить PostgreSQL на том же хостинге, что и бота?
Да, если хостинг поддерживает docker-compose: база описывается отдельным сервисом рядом с ботом, а данные хранятся в именованном томе. Учтите, что база тоже потребляет память, и она делится с приложением. Если не хочется следить за базой самому, подключите управляемую базу у облачного провайдера.
Сложно ли потом перейти с SQLite на PostgreSQL?
Если код работает с базой через ORM, например SQLAlchemy, Django ORM или Prisma, переход сводится к смене строки подключения и переносу данных. С сырыми SQL-запросами придётся проверить синтаксис: часть конструкций в базах отличается. Данные переносят утилитой pgloader или выгрузкой и загрузкой.
Сохранятся ли данные при обновлении кода?
Да, если данные лежат в постоянном хранилище. У обычного проекта это папка /data: всё, что приложение туда сохранило, остаётся при обновлении кода и перезапуске, а посмотреть и скачать файлы можно на вкладке «Данные». Если вы описали сервисы сами в docker-compose, постоянное хранилище — это именованные тома из вашего файла, и папки /data у такого проекта нет. Файлы, записанные мимо хранилища, при следующей публикации создаются заново. Ссылка проекта в любом случае остаётся прежней.
Можно ли запустить несколько сервисов сразу?
Да. Через docker-compose в одном проекте поднимается связка сервисов — например, приложение вместе с базой данных, кэшем и фоновым обработчиком. Числом сервисов мы не ограничиваем: считайте, что потолок задают память и процессор вашего тарифа, они делятся между сервисами проекта.
Где указать токены и другие секретные значения?
В проекте есть вкладка «Секреты» — там задаются значения из кода, например токен от BotFather. Мы храним их в зашифрованном виде: названия переменных вы видите, сами значения не показываем никому, включая вас.