|
1 | 1 | from datetime import datetime |
2 | 2 |
|
3 | | -from .handlers.custom_types import Question |
| 3 | +import sqlalchemy |
| 4 | +from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session |
4 | 5 |
|
| 6 | +from handlers import custom_types |
5 | 7 |
|
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): |
7 | 15 | pass |
8 | 16 |
|
9 | 17 |
|
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) |
16 | 23 |
|
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})' |
18 | 26 |
|
19 | 27 |
|
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()) |
26 | 61 |
|
27 | 62 |
|
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(): |
30 | 74 | """ |
31 | | - удалить вопрос, варианты ответа, |
32 | | - а также всю статистику связанную с ним из бд |
| 75 | + создать таблицы в бд |
33 | 76 | """ |
34 | | - pass |
| 77 | + engine = get_engine() |
| 78 | + Base.metadata.create_all(engine) |
35 | 79 |
|
36 | 80 |
|
37 | | -@decorator_add_connection |
| 81 | +@decorator_add_session |
38 | 82 | def add_question_to_db( |
39 | | - question_text: str, publish_date: datetime, connection=None |
| 83 | + question_text: str, publish_date: datetime, session: Session |
40 | 84 | ) -> int: |
41 | 85 | """ |
42 | 86 | добавить вопрос в бд |
43 | 87 | """ |
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 |
45 | 93 |
|
46 | 94 |
|
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): |
49 | 97 | """ |
50 | 98 | добавить ответ в бд |
51 | 99 | """ |
| 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 | + """ |
52 | 112 | pass |
53 | 113 |
|
54 | 114 |
|
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]: |
57 | 117 | """ |
58 | 118 | получить статистику пользователей |
59 | 119 | """ |
60 | 120 | return [[]] |
61 | 121 |
|
62 | 122 |
|
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]: |
65 | 125 | """ |
66 | 126 | получить личную статистику пользователя |
67 | 127 | """ |
68 | 128 | return [[]] |
69 | 129 |
|
70 | 130 |
|
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: |
73 | 133 | """ |
74 | 134 | получить случайный, неотвеченный вопрос из бд |
75 | 135 |
|
76 | 136 | return: Question |
77 | 137 | """ |
78 | | - return Question(id=0, text="") |
| 138 | + return custom_types.Question(id=0, text="") |
79 | 139 |
|
80 | 140 |
|
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]: |
83 | 143 | """ |
84 | 144 | получить ответы по заданному question_id |
85 | 145 | """ |
86 | 146 | return [] |
87 | 147 |
|
88 | 148 |
|
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): |
91 | 151 | """ |
92 | 152 | добавить голос пользователя выбранному варианту ответа |
93 | 153 | """ |
94 | 154 | pass |
95 | 155 |
|
96 | 156 |
|
97 | 157 | 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) |
0 commit comments