From f4146ea1675e1904a14a473c9b1b7f5e5dfa622e Mon Sep 17 00:00:00 2001 From: litoq Date: Mon, 20 Apr 2026 16:42:53 +0300 Subject: [PATCH] Add Redis support --- .env_example | 8 ++++++- README.md | 12 ++++++++-- main.py | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 1 + 4 files changed, 78 insertions(+), 3 deletions(-) diff --git a/.env_example b/.env_example index 8faa0cd..6189757 100644 --- a/.env_example +++ b/.env_example @@ -26,4 +26,10 @@ INFLUXDB3_DATABASE=sensors MONGO_ACTIVE=false MONGO_URI=mongodb://localhost:27017 MONGO_DB=movie_data -MONGO_COLLECTION=movies \ No newline at end of file +MONGO_COLLECTION=movies + +REDIS_ACTIVE=false +REDIS_HOST=localhost +REDIS_PORT=6379 +REDIS_DB=0 +REDIS_PASS= \ No newline at end of file diff --git a/README.md b/README.md index ba9e5d7..72db42a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ### Пример приложения для работы с БД -Небольшое десктоп-приложение на PyQt5 для работы с PostgreSQL, Neo4j, Apache AGE, InfluxDB 3 Core и MongoDB. +Небольшое десктоп-приложение на PyQt5 для работы с PostgreSQL, Neo4j, Apache AGE, InfluxDB 3 Core, MongoDB и Redis. ### Стек @@ -10,6 +10,7 @@ - Apache AGE — графовая БД в рамках PostgreSQL - InfluxDB 3 Core — БД временных рядов - MongoDB (pymongo) — документ-ориентированная БД +- Redis (redis-py) — in-memory key-value БД ### Скриншоты @@ -29,6 +30,7 @@ - Для Apache AGE: установленное расширение `age` в PostgreSQL и доступ к базе, где оно включено - Для InfluxDB 3 Core: запущенный сервер, заранее созданная база и токен с правами на запись и чтение - Для MongoDB: запущенный MongoDB сервер и доступ к целевой базе +- Для Redis: запущенный Redis сервер и доступ к нему ### Настройка окружения @@ -67,6 +69,12 @@ MONGO_ACTIVE=false # включить MongoDB, установив true MONGO_URI=mongodb://localhost:27017 MONGO_DB=movie_data MONGO_COLLECTION=movies + +REDIS_ACTIVE=false # включить Redis, установив true +REDIS_HOST=localhost +REDIS_PORT=6379 +REDIS_DB=0 +REDIS_PASS= ``` 2. Создайте и активируйте виртуальное окружение: @@ -101,4 +109,4 @@ pip install -r requirements.txt py main.py ``` -Для PostgreSQL, Neo4j, Apache AGE, InfluxDB 3 Core и MongoDB запросы выполняются только при `*_ACTIVE=true`. \ No newline at end of file +Для PostgreSQL, Neo4j, Apache AGE, InfluxDB 3 Core, MongoDB и Redis запросы выполняются только при `*_ACTIVE=true`. \ No newline at end of file diff --git a/main.py b/main.py index 0778ede..a93f8b7 100644 --- a/main.py +++ b/main.py @@ -12,6 +12,7 @@ from PyQt5.QtCore import QSize, Qt from PyQt5.QtWidgets import QApplication, QGridLayout, QHeaderView, QMainWindow, QTableWidget, QTableWidgetItem, QWidget MongoClient = importlib.import_module("pymongo").MongoClient +Redis = importlib.import_module("redis").Redis load_dotenv() @@ -45,6 +46,12 @@ MONGO_URI = os.getenv("MONGO_URI", "mongodb://localhost:27017") MONGO_DB = os.getenv("MONGO_DB", "movie_data") MONGO_COLLECTION = os.getenv("MONGO_COLLECTION", "movies") +REDIS_ACTIVE = os.getenv("REDIS_ACTIVE", "false").lower() == "true" +REDIS_HOST = os.getenv("REDIS_HOST", "localhost") +REDIS_PORT = int(os.getenv("REDIS_PORT", "6379")) +REDIS_DB = int(os.getenv("REDIS_DB", "0")) +REDIS_PASS = os.getenv("REDIS_PASS") + USER_SEED_DATA = [ (1, "Ivan", 15), (2, "Igor", 22), @@ -239,6 +246,46 @@ def select_mongo_movies(collection): return [document["title"] for document in cursor] +def connect_redis(): + return Redis( + host=REDIS_HOST, + port=REDIS_PORT, + db=REDIS_DB, + password=REDIS_PASS if REDIS_PASS else None, + decode_responses=True, + ) + + +def insert_redis_movies(client): + if client.exists("movies:seeded"): + print("Redis data is already seeded.") + return + + seed_movies = { + "Apollo 13": 1995, + "The Matrix": 1999, + "City of Angels": 1998, + "Toy Story": 1995, + "Alien": 1979, + } + for title, released in seed_movies.items(): + client.hset(f"movie:{title}", mapping={"title": title, "released": released}) + client.set("movies:seeded", "1") + print("Redis movies inserted.") + + +def select_redis_movies(client): + titles = [] + for key in client.scan_iter(match="movie:*"): + movie = client.hgetall(key) + if not movie: + continue + released = int(movie.get("released", 0)) + if 1990 <= released < 2000: + titles.append(movie.get("title", "")) + return sorted(title for title in titles if title) + + def load_users(): admin_conn = connect_postgres("postgres") try: @@ -428,4 +475,17 @@ if __name__ == "__main__": except Exception as error: print(f"MongoDB load failed: {error}") + if REDIS_ACTIVE: + try: + redis_client = connect_redis() + insert_redis_movies(redis_client) + redis_movies = select_redis_movies(redis_client) + + redis_window = DataWindow("redis", ["Info"], main_window, len(graph_windows)) + redis_window.load_data([(title,) for title in redis_movies]) + redis_window.show() + graph_windows.append(redis_window) + except Exception as error: + print(f"Redis load failed: {error}") + sys.exit(app.exec()) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index f629d37..3885a91 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,3 +4,4 @@ PyQt5 python-dotenv influxdb3-python pymongo +redis