Как подключить NocoDB к Django и FastAPI: интеграция pycodb

Repository Pattern и PycoDB: интеграция NocoDB на бэкенде

Владислав Ефименко
Владислав Ефименко Главный редактор
12 ноября 2025

Рассказываем, как интегрировать работу с платформой NocoDB на бэкенде с помощью Repository Pattern и модуля PycoDB.

Изображение записи

Классический сценарий: есть база данных и приложение на бэкенде. Для подключения достаточно знать адрес, порт, имя пользователя, пароль — и прямой доступ перед вами. Но что делать, если необходимо подключить no-code базу данных, которой можно управлять только через REST API? Есть ли способ интегрировать такие подключения в логику «красиво», не поломав архитектуру?

Меня зовут Влад, в свободное от работы время я занимаюсь разработкой. В этой статье расскажу, как мне удалось относительно нативно интегрировать работу с платформой NocoDB на бэкенде, какие можно использовать паттерны и зачем мне понадобилось разработать собственный Python-модуль.

Особенности работы с NocoDB

NocoDB — это платформа с открытым исходным кодом, которая превращает базы данных в удобные таблицы и интерфейсы.

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

Создание базы данных в NocoDB

Допустим, ваш сотрудник создает базу с клиентами: все удобно, за пределы графического интерфейса выходить не нужно. Таблицы созданной базы поддерживают полный функционал NocoDB. Но все просто ровно до тех пор, пока вы не решите подключиться к базе со своего бэкенда. Спойлер: напрямую, например, через ORM вроде Django ORM или SQLAlchemy у вас это сделать не получится. Потому что к созданной внутри NocoDB базе доступ будет только через REST API.

NocoDB, пример созданной таблицы.
NocoDB, пример созданной таблицы.

Подключение внешней базы данных в NocoDB

Если же вам нужно прямое подключение к базе данных, например PostgreSQL или MySQL, при этом важно сохранить графическую оболочку для других участников проекта, можно создать интеграцию.

Интерфейс подключения внешних баз данных в NocoDB.
Интерфейс подключения внешних баз данных в NocoDB.

Тогда NocoDB становится «прослойкой» c GUI и REST API, что в большинстве случаев правильно. Ведь вы получаете возможность напрямую подключиться к базе данных с бэкенда и не теряете в производительности.

Однако вы теряете полную интеграцию с функционалом NocoDB. Встроенные базы создаются и управляются напрямую, что обеспечивает максимальную совместимость — например, с триггерами, связями между таблицами, интерфейсом по умолчанию и прочим. Внешняя база данных может не поддерживать все «фичи» NocoDB из коробки. Кроме того, прямое подключение тесно связано с логикой ORM, из-за чего, например, при смене фреймворка придется переписывать слой бизнес-логики.

Выводы

REST API NocoDB — в целом, универсальный вариант подключения, если ваш проект небольших или средних размеров. Однако даже в таком случае важно сделать оговорку: для моделей вашей бизнес-логики, к которым пользователи обращаются с высокой частотой, все равно лучше использовать внешнюю базу данных с подключением напрямую. Это будет и производительнее, и безопаснее.

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

Интеграция NocoDB

Допустим, вы определили, что чувствительные и часто обновляемые данные будете хранить во внешней базе данных, с которой можно работать посредством ORM. Тем временем «наиболее статичные» данные, например список товаров, будут храниться в базе NocoDB. Тогда сотрудникам будет проще ими управлять: актуализировать стоимость, информацию о количестве и не только.

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

Repository

Обычно я выношу всю бизнес-логику подальше от функций представления — так архитектура становится чище и в целом логичнее. Так, если пришел запрос на список товаров, мы можем обратиться к списку объектов через Product.objects.filter(name=’Творог’) и вернуть json. А если поступил запрос на покупку, то достаточно вызвать пользовательский метод buy — и вернуть результат, например номер продукта.

Нам нужно в том же models.py научиться локанично описывать свои модели, так называемые репозитории, которые будут инкапсулировать логику доступа «к другим данным» (в нашем случае — к NocoDB) и предоставлять чистый абстрактный интерфейс для выполнения запросов и операций. Такой подход называют Repository Pattern.


      DataProxy([<DataItem Id=1, username=username1, Date time=2025-11-11 21:31:13+00:00, hash=hash1>, <DataItem Id=2, username=username2, Date time=2025-11-11 21:31:24+00:00, hash=hash2>, <DataItem Id=3, username=username3, Date time=2025-11-11 21:31:29+00:00, hash=hash3>, <DataItem Id=4, username=username4, Date time=2025-11-11 21:31:32+00:00, hash=hash4>])

Выше — простая реализация Repository, на базе которого можно будет создавать модели со своими пользовательскими методами. Здесь можно «творить» как хочется — например, я добавил динамический интерфейс allowed_methods, который блокирует нежелательный доступ к методам репозитория, если они явно не разрешены. Вот, как это выглядит на практике:


      DataProxy([<DataItem Id=1, username=username1, Date time=2025-11-11 21:31:13+00:00, hash=hash1>, <DataItem Id=2, username=username2, Date time=2025-11-11 21:31:24+00:00, hash=hash2>, <DataItem Id=3, username=username3, Date time=2025-11-11 21:31:29+00:00, hash=hash3>, <DataItem Id=4, username=username4, Date time=2025-11-11 21:31:32+00:00, hash=hash4>])

Как видим, мы создали модель Transactions.Shop, которая наследуется от Repository и явно указывает, какие методы разрешены: только регистрация новых транзакций, чтобы нельзя было считать чужие. Но что такое data_source?

ModelData

Repository должен брать откуда-то данные, для этого у него есть сервисный слой приложения (services/modeldata) — ModelData, который реализует прямой доступ к REST API NocoDB. В нашем примере за доступ отвечает TransactionsData:


      DataProxy([<DataItem Id=1, username=username1, Date time=2025-11-11 21:31:13+00:00, hash=hash1>, <DataItem Id=2, username=username2, Date time=2025-11-11 21:31:24+00:00, hash=hash2>, <DataItem Id=3, username=username3, Date time=2025-11-11 21:31:29+00:00, hash=hash3>, <DataItem Id=4, username=username4, Date time=2025-11-11 21:31:32+00:00, hash=hash4>])

Иначе говоря: есть база данных Transactions, внутри которой — таблица Shop. Ключ и параметры доступа (view_id и table_id) можно взять из самого NocoDB. При этом вся основная логика уже реализована в моем модуле PycoDB.

Я написал PycoDB, так как сам активно использую NocoDB для хранения данных приложения. Это довольно простой модуль — но этим он и отличается от аналогичных решений. Так что смело делайте форк, предлагайте улучшения и используйте в своих проектах.

Итого, используя Repository Pattern и сервисный слой, который я называю ModelData, вы можете легко работать с базами данных по REST API в ORM-based формате. Но это мы начали «со сложного». Если вам просто нужен удобный интерфейс для работы с NocoDB, можно использовать PycoDB в отрыве от всего остального.

Погружение в PycoDB

Установка и начало работы

1. Для начала создадим базу данных и таблицу. Пусть это будет некая база SpecificData с таблицей Topics, которая заполнена тестовыми значениями.

Тестовая таблица SpecificData.Topics.
Тестовая таблица SpecificData.Topics.

2. Далее установим модули pycodb и requests с помощью менеджера пакетов PyPi:


      DataProxy([<DataItem Id=1, username=username1, Date time=2025-11-11 21:31:13+00:00, hash=hash1>, <DataItem Id=2, username=username2, Date time=2025-11-11 21:31:24+00:00, hash=hash2>, <DataItem Id=3, username=username3, Date time=2025-11-11 21:31:29+00:00, hash=hash3>, <DataItem Id=4, username=username4, Date time=2025-11-11 21:31:32+00:00, hash=hash4>])

3. Отлично. Теперь можем импортировать модуль в код своего сервиса, прописать домен или IP-адрес, по которому доступен NocoDB, и ключ доступа:


      DataProxy([<DataItem Id=1, username=username1, Date time=2025-11-11 21:31:13+00:00, hash=hash1>, <DataItem Id=2, username=username2, Date time=2025-11-11 21:31:24+00:00, hash=hash2>, <DataItem Id=3, username=username3, Date time=2025-11-11 21:31:29+00:00, hash=hash3>, <DataItem Id=4, username=username4, Date time=2025-11-11 21:31:32+00:00, hash=hash4>])

4. Следующим шагом нужно описать структуру. Для этого нам понадобятся два основных суперкласса, от которых будет наследоваться ModelData: класс базы данных и таблицы.


      DataProxy([<DataItem Id=1, username=username1, Date time=2025-11-11 21:31:13+00:00, hash=hash1>, <DataItem Id=2, username=username2, Date time=2025-11-11 21:31:24+00:00, hash=hash2>, <DataItem Id=3, username=username3, Date time=2025-11-11 21:31:29+00:00, hash=hash3>, <DataItem Id=4, username=username4, Date time=2025-11-11 21:31:32+00:00, hash=hash4>])

Получение данных

Можно приступать к работе с NocoDB. Сейчас REST API максимально скрыт за объектной моделью (но без лишних абстракций, так как это сервисный слой) и мы можем, например, вывести список всех записей:


      DataProxy([<DataItem Id=1, username=username1, Date time=2025-11-11 21:31:13+00:00, hash=hash1>, <DataItem Id=2, username=username2, Date time=2025-11-11 21:31:24+00:00, hash=hash2>, <DataItem Id=3, username=username3, Date time=2025-11-11 21:31:29+00:00, hash=hash3>, <DataItem Id=4, username=username4, Date time=2025-11-11 21:31:32+00:00, hash=hash4>])

Вывод:


      DataProxy([<DataItem Id=1, username=username1, Date time=2025-11-11 21:31:13+00:00, hash=hash1>, <DataItem Id=2, username=username2, Date time=2025-11-11 21:31:24+00:00, hash=hash2>, <DataItem Id=3, username=username3, Date time=2025-11-11 21:31:29+00:00, hash=hash3>, <DataItem Id=4, username=username4, Date time=2025-11-11 21:31:32+00:00, hash=hash4>])

Отлично! Мы получили в качестве объектов все записи в таблице Topics. 

Фильтрация данных

Если нет цели получать все подряд данные, можем воспользоваться методом filter:


      filtered_topics = Transactions(table_name='Topics').filter(where='(username,eq,username1)')
print(filtered_topics)

Вывод:


      DataProxy([<DataItem Id=1, username=username1, Date time=2025-11-11 21:31:13+00:00, hash=hash1>])

В целом, с помощью метода filter можно задавать любые query-параметры, упрощающие получение данных из NocoDB. Полный список можно посмотреть в таблице.

Получение определенных полей

Допустим, что в таблице есть конфиденциальные данные, которые не стоит лишний раз получать на бэкенде во избежании утечек. В таком случае можно воспользоваться методом values:


      limited_topics = Transactions(table_name='Topics').values(['Id', 'username'])
print(limited_topics)

Вывод:


      DataProxy([<DataItem Id=1, username=username1>, <DataItem Id=2, username=username2>, <DataItem Id=3, username=username3>, <DataItem Id=4, username=username4>])

Добавление данных

Наконец, если нужно добавить новую запись в таблицу, достаточно использовать метод append и параметр target:


      Transactions(table_name='Topics').append(target={
   'username':'username9999', 'hash':'hash9999'
})

new_topic = Transactions(table_name='Topics').filter(where='(username,eq,username9999)')
print(new_topic)

Вывод:


      DataProxy([<DataItem Id=5, username=username9999, Date time=2025-11-11 22:23:41+00:00, hash=hash9999>])

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

Заключение

Надеюсь, мой материал оказался для вас полезным. Repository Pattern — то, к чему я пришел не сразу, так как старался лишний раз не прибегать к no-code базам данных. На деле же это довольно удобное для абстрактного слоя решение, к которому можно адаптироваться, как мы выяснили в этой статье.