Skip to content

Commit e94c206

Browse files
upgrade db adapter
1 parent 24fc71a commit e94c206

File tree

4 files changed

+144
-39
lines changed

4 files changed

+144
-39
lines changed

example/db_adapter.py

Lines changed: 99 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,160 @@
11
from datetime import datetime
22

3-
from .handlers.custom_types import Question
3+
import sqlalchemy
4+
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session
45

6+
from handlers import custom_types
57

6-
def get_connection_to_data_base():
8+
USERNAME = 'umschooluser'
9+
PASSWORD = 'umschoolpswd'
10+
DATABASE_NAME = 'umschooldb'
11+
PORT = 6432
12+
13+
14+
class Base(DeclarativeBase):
715
pass
816

917

10-
def decorator_add_connection(func):
11-
def wrapper(*args, **kwargs):
12-
connection = get_connection_to_data_base()
13-
result = func(*args, **kwargs, connection=connection)
14-
connection.close()
15-
return result
18+
class Question(Base):
19+
__tablename__ = 'question'
20+
id: Mapped[int] = mapped_column(primary_key=True)
21+
question_text: Mapped[str] = mapped_column(sqlalchemy.String(255))
22+
publish_date: Mapped[datetime] = mapped_column(sqlalchemy.DateTime)
1623

17-
return wrapper
24+
def __repr__(self) -> str:
25+
return f'Question(id={self.id}, question_text={self.question_text}, publish_date={self.publish_date})'
1826

1927

20-
@decorator_add_connection
21-
def create_tables_from_db(connection=None):
22-
"""
23-
создать таблицы в бд
24-
"""
25-
pass
28+
class Choice(Base):
29+
__tablename__ = 'choice'
30+
id: Mapped[int] = mapped_column(primary_key=True)
31+
choice_text: Mapped[str] = mapped_column(sqlalchemy.String(255))
32+
votes: Mapped[int] = mapped_column(sqlalchemy.Integer, default=0)
33+
question_id: Mapped[int] = mapped_column(sqlalchemy.ForeignKey('question.id'))
34+
35+
def __repr__(self) -> str:
36+
return f'Choice(id={self.id}, choice_text={self.choice_text}, votes={self.votes}, question_id={self.question_id})'
37+
38+
39+
class UserStat(Base):
40+
__tablename__ = 'user_stat'
41+
id: Mapped[int] = mapped_column(primary_key=True)
42+
tg_user_id: Mapped[int] = mapped_column(sqlalchemy.Integer)
43+
question_id: Mapped[int] = mapped_column(sqlalchemy.ForeignKey('question.id'))
44+
choice_id: Mapped[int] = mapped_column(sqlalchemy.ForeignKey('choice.id'))
45+
46+
def __repr__(self) -> str:
47+
return f'UserStat(id={self.id}, tg_user_id={self.tg_user_id}, question_id={self.question_id}, choice_id={self.choice_id})'
48+
49+
50+
def get_engine():
51+
return sqlalchemy.create_engine('postgresql://{username}:{password}@localhost:{port}/{database_name}'.format(
52+
username=USERNAME,
53+
password=PASSWORD,
54+
port=PORT,
55+
database_name=DATABASE_NAME,
56+
))
57+
58+
59+
def get_session() -> Session:
60+
return Session(get_engine())
2661

2762

28-
@decorator_add_connection
29-
def delete_question_by_id_db(question_id: int, connection=None):
63+
def decorator_add_session(func):
64+
def wrapper(*args, **kwargs):
65+
session = get_session()
66+
try:
67+
return func(*args, session=session, **kwargs)
68+
finally:
69+
session.close()
70+
return wrapper
71+
72+
73+
def create_tables_in_db():
3074
"""
31-
удалить вопрос, варианты ответа,
32-
а также всю статистику связанную с ним из бд
75+
создать таблицы в бд
3376
"""
34-
pass
77+
engine = get_engine()
78+
Base.metadata.create_all(engine)
3579

3680

37-
@decorator_add_connection
81+
@decorator_add_session
3882
def add_question_to_db(
39-
question_text: str, publish_date: datetime, connection=None
83+
question_text: str, publish_date: datetime, session: Session
4084
) -> int:
4185
"""
4286
добавить вопрос в бд
4387
"""
44-
pass
88+
with session.begin():
89+
question = Question(question_text=question_text, publish_date=publish_date)
90+
session.add(question)
91+
session.commit()
92+
return question.id
4593

4694

47-
@decorator_add_connection
48-
def add_choice_to_db(choice_text: str, question_id: int, connection=None):
95+
@decorator_add_session
96+
def add_choice_to_db(choice_text: str, question_id: int, session: Session):
4997
"""
5098
добавить ответ в бд
5199
"""
100+
with session.begin():
101+
choice = Choice(choice_text=choice_text, question_id=question_id)
102+
session.add(choice)
103+
session.commit()
104+
105+
106+
@decorator_add_session
107+
def delete_question_by_id_db(question_id: int, session: Session):
108+
"""
109+
удалить вопрос, варианты ответа,
110+
а также всю статистику связанную с ним из бд
111+
"""
52112
pass
53113

54114

55-
@decorator_add_connection
56-
def get_all_stat(connection=None) -> list[list]:
115+
@decorator_add_session
116+
def get_all_stat(session: Session) -> list[list]:
57117
"""
58118
получить статистику пользователей
59119
"""
60120
return [[]]
61121

62122

63-
@decorator_add_connection
64-
def get_personal_stat(telegram_id: int, connection=None) -> list[list]:
123+
@decorator_add_session
124+
def get_personal_stat(telegram_id: int, session: Session) -> list[list]:
65125
"""
66126
получить личную статистику пользователя
67127
"""
68128
return [[]]
69129

70130

71-
@decorator_add_connection
72-
def get_random_question(telegram_id: int, connection=None) -> Question:
131+
@decorator_add_session
132+
def get_random_question(telegram_id: int, session: Session) -> custom_types.Question:
73133
"""
74134
получить случайный, неотвеченный вопрос из бд
75135
76136
return: Question
77137
"""
78-
return Question(id=0, text="")
138+
return custom_types.Question(id=0, text="")
79139

80140

81-
@decorator_add_connection
82-
def get_choices_by_question_id(question_id: int, connection=None) -> list[str]:
141+
@decorator_add_session
142+
def get_choices_by_question_id(question_id: int, session: Session) -> list[str]:
83143
"""
84144
получить ответы по заданному question_id
85145
"""
86146
return []
87147

88148

89-
@decorator_add_connection
90-
def add_user_vote_db(choice_id: int, telegram_id: int, connection=None):
149+
@decorator_add_session
150+
def add_user_vote_db(choice_id: int, telegram_id: int, session: Session):
91151
"""
92152
добавить голос пользователя выбранному варианту ответа
93153
"""
94154
pass
95155

96156

97157
if __name__ == "__main__":
98-
create_tables_from_db()
158+
create_tables_in_db()
159+
add_question_to_db("test-question", datetime.now())
160+
add_choice_to_db("test-choice", 20)

example/docker-compose.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
version: "3.9"
2+
services:
3+
postgres:
4+
container_name: postgres_container
5+
image: postgres:16.1-alpine3.18
6+
environment:
7+
POSTGRES_DB: "umschooldb"
8+
POSTGRES_USER: "umschooluser"
9+
POSTGRES_PASSWORD: "umschoolpswd"
10+
PGDATA: "/var/lib/postgresql/data/pgdata"
11+
volumes:
12+
- umschooldb-data:/var/lib/postgresql/data
13+
ports:
14+
- "6432:5432"
15+
restart: unless-stopped
16+
networks:
17+
- postgres
18+
19+
pgadmin:
20+
container_name: pgadmin_container
21+
image: dpage/pgadmin4:8.13
22+
environment:
23+
PGADMIN_DEFAULT_EMAIL: "[email protected]"
24+
PGADMIN_DEFAULT_PASSWORD: "pgadminpswd"
25+
PGADMIN_CONFIG_SERVER_MODE: "False" # To allow running in desktop mode
26+
volumes:
27+
- pgadmin-data:/var/lib/pgadmin
28+
ports:
29+
- "5050:80"
30+
restart: unless-stopped
31+
networks:
32+
- postgres
33+
34+
volumes:
35+
umschooldb-data:
36+
pgadmin-data:
37+
38+
networks:
39+
postgres:
40+
driver: bridge

example/main.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@
33

44
import telebot
55

6-
from db_adapter import create_tables_from_db
6+
from db_adapter import create_tables_in_db
77
from handlers import register_handlers
88
from init_bot import create_bot
99

1010

1111
telebot.logger.setLevel(logging.DEBUG) # Outputs messages to console.
1212

1313
if __name__ == "__main__":
14-
create_tables_from_db()
14+
create_tables_in_db()
1515
bot = create_bot(os.getenv('TG_TOKEN'))
1616
register_handlers(bot)
1717
bot.add_custom_filter(telebot.custom_filters.StateFilter(bot))

example/requirements.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
SQLAlchemy==2.0
2+
pyTelegramBotAPI==4.24.0
3+
psycopg2-binary==2.9.10

0 commit comments

Comments
 (0)