SCDB
Open Source система для автоматического парсинга и обработки данных об образовательных учреждениях из открытых источников. Включает Server (REST API) и Updater (парсер данных).
Образовательных учреждений
Федеральных округов
Регионов
Городов
Общеобразовательные
47,251
Среднее профессиональное образование
5,038
Дошкольное образование
1,940
Высшее образование
732
SCDB (School Database) - это система управления базой данных образовательных организаций, состоящая из двух основных микросервисов: SCDB Server (REST API) и SCDB Updater (система обновления данных). Данные собираются из открытых источников и других официальных реестров.
Основной язык разработки для SCDB Server и SCDB Updater. Выбран за высокую производительность при обработке XML данных
Система обновления данных с поддержкой типов учреждений и географического расположения. Парсит сырые данные о сертификатах, импортирует в базу данных
REST API сервер на Go с Gin framework. Предоставляет эндпоинты для получения данных с фильтрацией по регионам, типам образования и пагинацией
Реляционная база данных с таблицами для организаций, регионов, городов, федеральных округов и типов образования. Полная структура связей
Готовые Docker-образы для быстрого развертывания всей системы. Возможность поставки demo режима
Полностью открытый исходный код под MIT лицензией. Два независимых репозитория: Server и Updater для гибкой архитектуры
Если вам хочется посмотреть итоговый результат и не хочется разворачивать базу данных и все это дело — я могу скинуть вам готовый демо режим в Docker образе с готовой пошаговой простой инструкцией!😊
Основной язык разработки для SCDB Server и SCDB Updater. Высокая производительность и простота развертывания
Реляционная база данных для хранения структурированных данных с индексами для быстрого поиска
Контейнеризация для упрощения развертывания и обеспечения консистентности окружения
Быстрый HTTP веб-фреймворк для Go, используемый в SCDB Server для создания REST API
Система состоит из двух независимых микросервисов: SCDB Updater для парсинга и обновления данных и SCDB Server для предоставления REST API.
Система обновления данных выполняет последовательную инициализацию: федеральные округа → регионы → города → типы организаций → образовательные учреждения. Использует транзакции PostgreSQL для атомарности операций и COPY для быстрой загрузки больших объемов данных.
package main
import (
"gitlab.com/scdb/updater/internal/config"
"gitlab.com/scdb/updater/internal/database"
"gitlab.com/scdb/updater/internal/logger"
"gitlab.com/scdb/updater/internal/services"
)
func main() {
config.LoadConfig()
database.Connect()
// Последовательная инициализация данных
districts := services.SeedFederalDistricts()
services.SeedRegions(districts)
services.SeedCities()
services.SeedOrganisationsTypes()
services.SeedOrganisations()
defer database.DB.Close()
}
Процесс загрузки образовательных учреждений оптимизирован для работы с большими объемами данных: отключение триггеров, использование временных таблиц, COPY операции, пакетная обработка по 1000 записей, исключение дубликатов через DISTINCT ON.
func SeedOrganisations() {
start := time.Now()
data := utils.GetDataParsedXML()
// Транзакция для атомарности операций
tx, err := database.DB.Begin()
if err != nil {
logger.Fatal("Ошибка при начале транзакции:", err)
}
// Отключаем триггеры для ускорения
_, err = tx.Exec("ALTER TABLE education_organizations DISABLE TRIGGER ALL;")
// Создаем временную таблицу для COPY
_, err = tx.Exec(`
CREATE TEMP TABLE temp_education_organizations (
id text, full_name text, short_name text,
head_edu_org_id text, is_branch boolean,
post_address text, phone text, fax text,
email text, web_site text, ogrn text,
inn text, kpp text, head_post text,
head_name text, form_name text,
kind_name text, type_name text,
fk_city_id text, fk_region_id int,
fk_federal_district_id int,
fk_education_type_key text
) ON COMMIT DROP;
`)
// Используем COPY для быстрой загрузки
stmt, err := tx.Prepare(pq.CopyIn("temp_education_organizations", ...))
// Обрабатываем данные пакетами по 1000 записей
for i, cert := range data.Certificates {
org := cert.ActualEducationOrganization
cityId, regionId, federalDistrictId, orgType :=
utils.ProcessOrganization(org, citiesMap, regionsMap, ...)
_, err = stmt.Exec(org.ID, org.FullName, ...)
}
// Вставляем из временной таблицы с исключением дубликатов
_, err = tx.Exec(`
INSERT INTO education_organizations
SELECT DISTINCT ON (id) *
FROM temp_education_organizations
ON CONFLICT (id) DO NOTHING;
`)
tx.Commit()
}
REST API сервер на Go с использованием Gin framework. Включает демо-лимиты для ограничения запросов, CORS настройки. Предоставляет эндпоинты для получения организаций с фильтрацией по федеральным округам, регионам, городам, типам образования, поиском и пагинацией.
// SCDB Server - настройка роутера
func SetupRouter() *gin.Engine {
router := gin.Default()
// Инициализируем демо-лимитер
middleware.InitDemoLimiter()
// CORS настройки
router.Use(cors.New(cors.Config{
AllowOrigins: []string{config.AppConfig.WEBUrl},
AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
AllowHeaders: []string{"Origin", "Content-Type", "Authorization"},
ExposeHeaders: []string{"Content-Length", "X-Demo-Image-ID", "X-Demo-Requests-Used", "X-Demo-Requests-Limit", "X-Demo-Requests-Remaining"},
AllowCredentials: true,
MaxAge: 12 * time.Hour,
}))
// Публичные маршруты
public := router.Group("/api")
{
public.POST("/register", controllers.Register)
public.POST("/login", controllers.Login)
public.GET("/stats", controllers.GetStats)
public.GET("/demo/stats", controllers.GetDemoStats)
}
// Защищенные маршруты с демо-лимитами
protected := router.Group("/api")
protected.Use(middleware.DemoLimitMiddleware())
protected.Use(middleware.AuthMiddleware())
{
protected.GET("/organizations", controllers.GetOrganizations)
protected.GET("/organizations/:id", controllers.GetOrganisationById)
}
return router
}
// Контроллер для получения организаций
func GetOrganizations(c *gin.Context) {
search := c.Query("search")
page, _ := strconv.Atoi(c.Query("page"))
if page < 1 { page = 1 }
perPage, _ := strconv.Atoi(c.Query("per_page"))
if perPage < 1 { perPage = 20 }
// Ограничения в демо-режиме
if config.AppConfig.DemoMode && perPage > 50 {
perPage = 50
}
// Параметры фильтрации
var federalDistrictID *int
if fdID, err := strconv.Atoi(c.Query("federal_district_id")); err == nil {
federalDistrictID = &fdID
}
var regionID *int
if rID, err := strconv.Atoi(c.Query("region_id")); err == nil {
regionID = &rID
}
var cityID *string
if cID := c.Query("city_id"); cID != "" {
cityID = &cID
}
var educationTypeKey *string
if etKey := c.Query("education_type_key"); etKey != "" {
educationTypeKey = &etKey
}
organizations, total, err := repository.GetOrganizations(
search, federalDistrictID, regionID, cityID,
educationTypeKey, perPage, (page-1)*perPage,
)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{
"data": organizations,
"total": total,
"page": page,
"per_page": perPage,
"total_pages": (total + perPage - 1) / perPage,
})
}
PostgreSQL 17.4 с полной структурой связей между таблицами. Основная таблица education_organizations содержит все данные об учреждениях с внешними ключами на города, регионы, федеральные округа и типы образования. Оптимизированные индексы для быстрого поиска.
-- Структура базы данных
CREATE TABLE education_organizations (
id text PRIMARY KEY,
full_name text NOT NULL,
short_name text,
head_edu_org_id text,
is_branch boolean DEFAULT false,
post_address text,
phone text,
fax text,
email text,
web_site text,
ogrn text,
inn text,
kpp text,
head_post text,
head_name text,
form_name text,
kind_name text,
type_name text,
fk_city_id text REFERENCES cities(id),
fk_region_id int REFERENCES regions(id),
fk_federal_district_id int REFERENCES federal_districts(id),
fk_education_type_key text REFERENCES education_types(key)
);
-- Индексы для быстрого поиска
CREATE INDEX idx_orgs_region ON education_organizations(fk_region_id);
CREATE INDEX idx_orgs_city ON education_organizations(fk_city_id);
CREATE INDEX idx_orgs_type ON education_organizations(fk_education_type_key);
Готовый Docker Compose файл для быстрого развертывания системы. Включает PostgreSQL 17.4 с healthcheck, автоматической инициализацией базы данных через скрипты в docker-entrypoint-initdb.d, персистентным хранилищем и SCDB Server с зависимостью от готовности базы данных. Использует .env файл для конфигурации переменных окружения.
# Docker Compose для SCDB
version: "3.8"
services:
db:
image: postgres:17.4
container_name: scdb-postgres
restart: always
env_file: .env
ports:
- "5432:5432"
volumes:
- db_data:/var/lib/postgresql/data
- ./internal/database/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d db"]
interval: 5s
timeout: 5s
retries: 5
app:
build: .
container_name: scdb-server
restart: always
env_file: .env
ports:
- "8080:8080"
depends_on:
db:
condition: service_healthy
volumes:
db_data:
В разработке: система API-ключей и авторизации, кеширование с Redis для повышения производительности, экспорт данных в CSV/Excel форматы, CLI интерфейс для импорта данных, система логирования и мониторинга производительности, веб-интерфейс для управления данными.
Данным примером предствленные некоторые организации Центрального федерального округа
{
"id": "0B0E1113-0B13-0C10-1311-0D130F0D120F100F0E0D",
"full_name": "Автономная некоммерческая организация высшего образования «Институт кино и телевидения (ГИТР)»",
"short_name": "АНО ВО ГИТР",
"head_edu_org_id": "",
"is_branch": false,
"post_address": "123007, г. Москва, Хорошевское ш., д. 32 А",
"phone": "+7(495) 787-65-11",
"fax": "",
"email": "aim@gitr.ru",
"web_site": "www.gitr.ru",
"ogrn": "1167700069228",
"inn": "7714424400",
"kpp": "771401001",
"head_post": "47805583f3fe4c749a9a1e921e343336",
"head_name": "Литовчин Юрий Михайлович",
"form_name": "Автономные некоммерческие организации",
"kind_name": "Начальная школа - детский сад",
"type_name": "Образовательная организация высшего образования",
"region_name": "",
"federal_district_short_name": "",
"federal_district_name": "Центральный федеральный округ",
"created_at": "0001-01-01T00:00:00Z",
"updated_at": "0001-01-01T00:00:00Z",
"city_id": "0c5b2444-70a0-4932-980c-b4dc0d3f02b5",
"region_id": 77,
"federal_district_id": 1,
"education_type_key": "general_education"
}
⚠️ Внимание: Портал открытых данных бывает недоступен. Сырой XML файл весит 1.2GB - мы не стали засорять GitHub этим файлом. Если у вас не получается скачать сырой XML, напишите в Telegram - с удовольствием отправим вам файл.
Ответы на популярные вопросы о базе данных образовательных организаций
SCDB Server поставляется в виде Docker-образа. Для запуска выполните `docker-compose up -d` - это запустит PostgreSQL 17.4 и SCDB Server. Сервер будет доступен по адресу http://localhost:8080. Подробная инструкция в README на GitHub.
Для импорта данных используйте SCDB Updater - отдельный сервис для парсинга данных из реестра организаций Рособрнадзора. Updater поддерживает 10 типов образовательных учреждений и выполняет пошаговый импорт: федеральные округа → регионы → города → типы образования → организации.
SCDB поддерживает 10 типов: дошкольное, общее, среднее профессиональное, высшее, дополнительное, профессиональное обучение, специальное, военное, религиозное и международное образование. Каждый тип имеет ключевые слова для автоматической классификации.
SCDB Server предоставляет эндпоинты: GET /api/organizations/{id} - получение организации по ID, GET /api/organizations - список с фильтрацией и пагинацией, GET /api/stats - статистика. Поддерживается фильтрация по регионам, типам образования, поиск по названию.
Да, SCDB Server поддерживает демо-режим с ограниченным набором тестовых данных. Для создания демо-образа используйте docker-compose.demo.yml и скрипт обфускации данных.
Да, SCDB Updater работает независимо от SCDB Server. Вы можете использовать его для парсинга данных в свою базу данных или для других целей. Это отдельный сервис с собственным репозиторием и конфигурацией.
В разработке: система API-ключей и авторизации, кеширование с Redis, экспорт данных в CSV/Excel, импорт данных через CLI, система логирования и мониторинга производительности.
Проект открыт для контрибьюторов! Есть два репозитория: SCDB Server и SCDB Updater. Можно создавать issues с багами или feature requests, делать pull requests. Особенно приветствуются улучшения безопасности и производительности.
Проект распространяется под MIT лицензией, что позволяет свободно использовать, модифицировать и распространять код как в коммерческих, так и в некоммерческих целях.
SCDB состоит из двух репозиториев: SCDB Server (REST API) и SCDB Updater (парсер данных). Любой может внести свой вклад в развитие системы.
Поддержите проект, поставив звезду на GitHub репозитории. Это помогает проекту быть замеченным сообществом.
Star на GitHubНашли ошибку в SCDB Server или SCDB Updater? Создайте issue с подробным описанием проблемы.
Создать IssueЕсть идеи по улучшению API, безопасности или производительности? Предложите новые функции в issues.
ПредложитьГотовы внести код? Создайте fork, внесите изменения и отправьте pull request в любой из репозиториев.
Fork & PR