Это исключительно важный вопрос, который влияет на то, какие “фишки” базы данных мы можем использовать.
Я вспомнил, что в правилах твоего проекта (dicechess-lab/AGENTS.md) прямо указано: “SQLite: WAL mode for low-RAM devices”. Raspberry Pi 3 имеет всего 1 ГБ оперативной памяти и работает с SD-картой. Разворачивать полноценный PostgreSQL в Docker на RPi3 можно, но это “съест” много ресурсов. Для RPi3 и быстрых локальных тестов SQLite — идеальный выбор.
Однако у нас возникает проблема совместимости диалектов SQL, если мы хотим, чтобы один и тот же код (через SQLAlchemy или сырые SQL-миграции) работал и на SQLite (staging/local), и на PostgreSQL (production server ASUS).
Что есть в PostgreSQL, чего НЕТ в SQLite:
- Нативный тип
ENUM(о котором мы только что говорили). SQLite его не поддерживает. - Тип массивов
VARCHAR[](который я предложил для поляplayed_moves). В SQLite нет нативных массивов. - Нативный тип
UUID. В SQLite UUID хранится просто как строкаVARCHAR(36).
Как нам проектировать схему, чтобы она работала везде?
Нам нужно использовать “наименьший общий знаменатель”, который отлично работает в обеих базах:
-
Вместо ENUM используем
VARCHAR(20) + CHECKТот самый вариант, который я изначально написал в плане. В коде (Python/SQLAlchemy) мы создадим классEnum, и SQLAlchemy будет валидировать его на уровне приложения, а в саму базу (и в SQLite, и в Postgres) писать обычную текстовую строку'timeout'. Это гарантирует 100% совместимость. -
Вместо массивов
VARCHAR[]используемJSONПолеplayed_movesв таблицеturnsмы сделаем типаJSON(в Postgres это будет быстрыйJSONB, а в SQLite — текстовое поле с проверкой на валидный JSON). Список микро-ходов будет храниться как["b1c3", "e2e4"]. Оба движка умеют отлично работать с JSON. -
Вместо типа UUID используем
VARCHAR(36)Сами значения будут настоящими UUID, но в структуре таблиц мы определим их как строки.
Моя рекомендация по инфраструктуре:
- Local Dev (Твой Mac): Можно использовать SQLite для скорости разработки, либо поднять локальный PostgreSQL через Docker (чтобы среда была ближе к проду).
- Staging (Raspberry Pi 3): Однозначно SQLite (в режиме WAL). Легко, быстро, не убивает SD-карту лишними фоновыми процессами.
- Production Analytics (ASUS Server): Однозначно PostgreSQL. Когда ты загрузишь туда 10 миллионов партий, SQLite начнет тяжело дышать на сложных аналитических
JOIN-запросах со статистикой, а Postgres “проглотит” это благодаря параллельным запросам и большому объему оперативной памяти ASUS-сервера.
Итог: Если ты хочешь сохранить поддержку SQLite для RPi3, нам нужно вернуться к варианту VARCHAR + CHECK для поля termination и поменять VARCHAR[] на JSON для played_moves.
Согласен ли ты на такой компромисс ради универсальности кода?