Переделал модели бд
This commit is contained in:
parent
9af53e4982
commit
ccd1e209f1
14 changed files with 195 additions and 206 deletions
|
@ -12,7 +12,7 @@ file_template = %%(year)d-%%(month).2d-%%(day).2d_%%(slug)s
|
||||||
|
|
||||||
# sys.path path, will be prepended to sys.path if present.
|
# sys.path path, will be prepended to sys.path if present.
|
||||||
# defaults to the current working directory.
|
# defaults to the current working directory.
|
||||||
prepend_sys_path = .
|
prepend_sys_path = . app
|
||||||
|
|
||||||
# timezone to use when rendering the date within the migration file
|
# timezone to use when rendering the date within the migration file
|
||||||
# as well as the filename.
|
# as well as the filename.
|
||||||
|
|
113
app/chat/dao.py
113
app/chat/dao.py
|
@ -5,7 +5,12 @@ from app.database import async_session_maker, engine # noqa
|
||||||
from app.exceptions import UserAlreadyInChatException, UserAlreadyPinnedChatException
|
from app.exceptions import UserAlreadyInChatException, UserAlreadyPinnedChatException
|
||||||
from app.chat.shemas import SMessage
|
from app.chat.shemas import SMessage
|
||||||
from app.models.users import Users
|
from app.models.users import Users
|
||||||
from app.models.chat import Chats, Messages, UsersXChats, PinnedChats, PinnedMessages, Answers
|
from app.models.answer import Answer
|
||||||
|
from app.models.chat import Chats
|
||||||
|
from app.models.message import Message
|
||||||
|
from app.models.pinned_chat import PinnedChats
|
||||||
|
from app.models.pinned_message import PinnedMessages
|
||||||
|
from app.models.user_chat import UserChat
|
||||||
|
|
||||||
|
|
||||||
class ChatDAO(BaseDAO):
|
class ChatDAO(BaseDAO):
|
||||||
|
@ -22,13 +27,13 @@ class ChatDAO(BaseDAO):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def add_user_to_chat(user_id: int, chat_id: int) -> bool:
|
async def add_user_to_chat(user_id: int, chat_id: int) -> bool:
|
||||||
query = select(UsersXChats.user_id).where(UsersXChats.chat_id == chat_id)
|
query = select(UserChat.user_id).where(UserChat.chat_id == chat_id)
|
||||||
async with async_session_maker() as session:
|
async with async_session_maker() as session:
|
||||||
result = await session.execute(query)
|
result = await session.execute(query)
|
||||||
result = result.scalars().all()
|
result = result.scalars().all()
|
||||||
if user_id in result:
|
if user_id in result:
|
||||||
raise UserAlreadyInChatException
|
raise UserAlreadyInChatException
|
||||||
query = insert(UsersXChats).values(user_id=user_id, chat_id=chat_id)
|
query = insert(UserChat).values(user_id=user_id, chat_id=chat_id)
|
||||||
await session.execute(query)
|
await session.execute(query)
|
||||||
await session.commit()
|
await session.commit()
|
||||||
return True
|
return True
|
||||||
|
@ -36,10 +41,10 @@ class ChatDAO(BaseDAO):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def send_message(user_id: int, chat_id: int, message: str, image_url: str | None = None) -> SMessage:
|
async def send_message(user_id: int, chat_id: int, message: str, image_url: str | None = None) -> SMessage:
|
||||||
inserted_image = (
|
inserted_image = (
|
||||||
insert(Messages)
|
insert(Message)
|
||||||
.values(chat_id=chat_id, user_id=user_id, message=message, image_url=image_url)
|
.values(chat_id=chat_id, user_id=user_id, message=message, image_url=image_url)
|
||||||
.returning(
|
.returning(
|
||||||
Messages.id, Messages.message, Messages.image_url, Messages.chat_id, Messages.user_id, Messages.created_at
|
Message.id, Message.message, Message.image_url, Message.chat_id, Message.user_id, Message.created_at
|
||||||
)
|
)
|
||||||
.cte("inserted_image")
|
.cte("inserted_image")
|
||||||
)
|
)
|
||||||
|
@ -55,12 +60,12 @@ class ChatDAO(BaseDAO):
|
||||||
Users.avatar_image,
|
Users.avatar_image,
|
||||||
Users.username,
|
Users.username,
|
||||||
Users.avatar_hex,
|
Users.avatar_hex,
|
||||||
Answers.self_id,
|
Answer.self_id,
|
||||||
Answers.answer_id,
|
Answer.answer_id,
|
||||||
)
|
)
|
||||||
.select_from(inserted_image)
|
.select_from(inserted_image)
|
||||||
.join(Users, Users.id == inserted_image.c.user_id)
|
.join(Users, Users.id == inserted_image.c.user_id)
|
||||||
.join(Answers, Answers.self_id == inserted_image.c.id, isouter=True)
|
.join(Answer, Answer.self_id == inserted_image.c.id, isouter=True)
|
||||||
)
|
)
|
||||||
|
|
||||||
async with async_session_maker() as session:
|
async with async_session_maker() as session:
|
||||||
|
@ -73,22 +78,22 @@ class ChatDAO(BaseDAO):
|
||||||
async def get_message_by_id(message_id: int):
|
async def get_message_by_id(message_id: int):
|
||||||
query = (
|
query = (
|
||||||
select(
|
select(
|
||||||
Messages.id,
|
Message.id,
|
||||||
Messages.message,
|
Message.message,
|
||||||
Messages.image_url,
|
Message.image_url,
|
||||||
Messages.chat_id,
|
Message.chat_id,
|
||||||
Messages.user_id,
|
Message.user_id,
|
||||||
Messages.created_at,
|
Message.created_at,
|
||||||
Users.avatar_image,
|
Users.avatar_image,
|
||||||
Users.username,
|
Users.username,
|
||||||
Users.avatar_hex,
|
Users.avatar_hex,
|
||||||
Answers.self_id,
|
Answer.self_id,
|
||||||
Answers.answer_id,
|
Answer.answer_id,
|
||||||
)
|
)
|
||||||
.select_from(Messages)
|
.select_from(Message)
|
||||||
.join(Users, Users.id == Messages.user_id)
|
.join(Users, Users.id == Message.user_id)
|
||||||
.join(Answers, Answers.self_id == Messages.id, isouter=True)
|
.join(Answer, Answer.self_id == Message.id, isouter=True)
|
||||||
.where(Messages.id == message_id, Messages.visibility == True) #
|
.where(Message.id == message_id, Message.visibility == True) #
|
||||||
)
|
)
|
||||||
async with async_session_maker() as session:
|
async with async_session_maker() as session:
|
||||||
result = await session.execute(query)
|
result = await session.execute(query)
|
||||||
|
@ -98,7 +103,7 @@ class ChatDAO(BaseDAO):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def delete_message(message_id: int) -> bool:
|
async def delete_message(message_id: int) -> bool:
|
||||||
query = update(Messages).where(Messages.id == message_id).values(visibility=False)
|
query = update(Message).where(Message.id == message_id).values(visibility=False)
|
||||||
async with async_session_maker() as session:
|
async with async_session_maker() as session:
|
||||||
await session.execute(query)
|
await session.execute(query)
|
||||||
await session.commit()
|
await session.commit()
|
||||||
|
@ -120,10 +125,10 @@ class ChatDAO(BaseDAO):
|
||||||
LIMIT 15 OFFSET 0;
|
LIMIT 15 OFFSET 0;
|
||||||
"""
|
"""
|
||||||
messages_with_users = (
|
messages_with_users = (
|
||||||
select(Messages.__table__.columns, Users.__table__.columns, Answers.__table__.columns)
|
select(Message.__table__.columns, Users.__table__.columns, Answer.__table__.columns)
|
||||||
.select_from(Messages)
|
.select_from(Message)
|
||||||
.join(Users, Messages.user_id == Users.id)
|
.join(Users, Message.user_id == Users.id)
|
||||||
.join(Answers, Answers.self_id == Messages.id, isouter=True)
|
.join(Answer, Answer.self_id == Message.id, isouter=True)
|
||||||
.cte("messages_with_users")
|
.cte("messages_with_users")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -155,7 +160,7 @@ class ChatDAO(BaseDAO):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def edit_message(message_id: int, new_message: str, new_image_url: str) -> bool:
|
async def edit_message(message_id: int, new_message: str, new_image_url: str) -> bool:
|
||||||
query = update(Messages).where(Messages.id == message_id).values(message=new_message, image_url=new_image_url)
|
query = update(Message).where(Message.id == message_id).values(message=new_message, image_url=new_image_url)
|
||||||
async with async_session_maker() as session:
|
async with async_session_maker() as session:
|
||||||
await session.execute(query)
|
await session.execute(query)
|
||||||
await session.commit()
|
await session.commit()
|
||||||
|
@ -164,30 +169,30 @@ class ChatDAO(BaseDAO):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def add_answer(self_id: int, answer_id: int) -> SMessage:
|
async def add_answer(self_id: int, answer_id: int) -> SMessage:
|
||||||
answer = (
|
answer = (
|
||||||
insert(Answers)
|
insert(Answer)
|
||||||
.values(self_id=self_id, answer_id=answer_id)
|
.values(self_id=self_id, answer_id=answer_id)
|
||||||
.returning(Answers.self_id, Answers.answer_id)
|
.returning(Answer.self_id, Answer.answer_id)
|
||||||
.cte("answer")
|
.cte("answer")
|
||||||
)
|
)
|
||||||
|
|
||||||
query = (
|
query = (
|
||||||
select(
|
select(
|
||||||
Messages.id,
|
Message.id,
|
||||||
Messages.message,
|
Message.message,
|
||||||
Messages.image_url,
|
Message.image_url,
|
||||||
Messages.chat_id,
|
Message.chat_id,
|
||||||
Messages.user_id,
|
Message.user_id,
|
||||||
Messages.created_at,
|
Message.created_at,
|
||||||
Users.avatar_image,
|
Users.avatar_image,
|
||||||
Users.username,
|
Users.username,
|
||||||
Users.avatar_hex,
|
Users.avatar_hex,
|
||||||
answer.c.self_id,
|
answer.c.self_id,
|
||||||
answer.c.answer_id,
|
answer.c.answer_id,
|
||||||
)
|
)
|
||||||
.select_from(Messages)
|
.select_from(Message)
|
||||||
.join(Users, Users.id == Messages.user_id)
|
.join(Users, Users.id == Message.user_id)
|
||||||
.join(answer, answer.c.self_id == Messages.id, isouter=True)
|
.join(answer, answer.c.self_id == Message.id, isouter=True)
|
||||||
.where(Messages.id == self_id)
|
.where(Message.id == self_id)
|
||||||
)
|
)
|
||||||
|
|
||||||
async with async_session_maker() as session:
|
async with async_session_maker() as session:
|
||||||
|
@ -206,7 +211,7 @@ class ChatDAO(BaseDAO):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def delete_user(chat_id: int, user_id: int) -> bool:
|
async def delete_user(chat_id: int, user_id: int) -> bool:
|
||||||
query = delete(UsersXChats).where(UsersXChats.chat_id == chat_id, UsersXChats.user_id == user_id)
|
query = delete(UserChat).where(UserChat.chat_id == chat_id, UserChat.user_id == user_id)
|
||||||
async with async_session_maker() as session:
|
async with async_session_maker() as session:
|
||||||
await session.execute(query)
|
await session.execute(query)
|
||||||
await session.commit()
|
await session.commit()
|
||||||
|
@ -236,9 +241,9 @@ class ChatDAO(BaseDAO):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def get_pinned_chats(user_id: int):
|
async def get_pinned_chats(user_id: int):
|
||||||
chats_with_descriptions = (
|
chats_with_descriptions = (
|
||||||
select(UsersXChats.__table__.columns, Chats.__table__.columns)
|
select(UserChat.__table__.columns, Chats.__table__.columns)
|
||||||
.select_from(UsersXChats)
|
.select_from(UserChat)
|
||||||
.join(Chats, UsersXChats.chat_id == Chats.id)
|
.join(Chats, UserChat.chat_id == Chats.id)
|
||||||
.cte("chats_with_descriptions")
|
.cte("chats_with_descriptions")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -306,24 +311,24 @@ class ChatDAO(BaseDAO):
|
||||||
async def get_pinned_messages(chat_id: int) -> list[dict]:
|
async def get_pinned_messages(chat_id: int) -> list[dict]:
|
||||||
query = (
|
query = (
|
||||||
select(
|
select(
|
||||||
Messages.id,
|
Message.id,
|
||||||
Messages.message,
|
Message.message,
|
||||||
Messages.image_url,
|
Message.image_url,
|
||||||
Messages.chat_id,
|
Message.chat_id,
|
||||||
Messages.user_id,
|
Message.user_id,
|
||||||
Messages.created_at,
|
Message.created_at,
|
||||||
Users.avatar_image,
|
Users.avatar_image,
|
||||||
Users.username,
|
Users.username,
|
||||||
Users.avatar_hex,
|
Users.avatar_hex,
|
||||||
Answers.self_id,
|
Answer.self_id,
|
||||||
Answers.answer_id,
|
Answer.answer_id,
|
||||||
)
|
)
|
||||||
.select_from(PinnedMessages)
|
.select_from(PinnedMessages)
|
||||||
.join(Messages, PinnedMessages.message_id == Messages.id, isouter=True)
|
.join(Message, PinnedMessages.message_id == Message.id, isouter=True)
|
||||||
.join(Users, PinnedMessages.user_id == Users.id, isouter=True)
|
.join(Users, PinnedMessages.user_id == Users.id, isouter=True)
|
||||||
.join(Answers, Answers.self_id == Messages.id, isouter=True)
|
.join(Answer, Answer.self_id == Message.id, isouter=True)
|
||||||
.where(PinnedMessages.chat_id == chat_id, Messages.visibility == True)
|
.where(PinnedMessages.chat_id == chat_id, Message.visibility == True)
|
||||||
.order_by(Messages.created_at.desc())
|
.order_by(Message.created_at.desc())
|
||||||
)
|
)
|
||||||
async with async_session_maker() as session:
|
async with async_session_maker() as session:
|
||||||
result = await session.execute(query)
|
result = await session.execute(query)
|
||||||
|
|
|
@ -1,15 +1,19 @@
|
||||||
import sys
|
|
||||||
from os.path import abspath, dirname
|
|
||||||
from logging.config import fileConfig
|
from logging.config import fileConfig
|
||||||
|
|
||||||
from sqlalchemy import engine_from_config, pool
|
from sqlalchemy import engine_from_config, pool
|
||||||
from alembic import context
|
from alembic import context
|
||||||
|
|
||||||
sys.path.insert(0, dirname(dirname(abspath(__file__))))
|
|
||||||
|
|
||||||
from app.database import DATABASE_URL, Base
|
from app.database import DATABASE_URL, Base
|
||||||
from app.models.chat import Users, UsersVerificationCodes # noqa
|
from app.models.users import Users # noqa
|
||||||
from app.models.chat import Chats, Messages, UsersXChats, PinnedMessages, PinnedChats # noqa
|
from app.models.answer import Answer # noqa
|
||||||
|
from app.models.chat import Chats # noqa
|
||||||
|
from app.models.message import Message # noqa
|
||||||
|
from app.models.pinned_chat import PinnedChats # noqa
|
||||||
|
from app.models.pinned_message import PinnedMessages # noqa
|
||||||
|
from app.models.user_chat import UserChat # noqa
|
||||||
|
from app.models.user_avatar import UserAvatar # noqa
|
||||||
|
from app.models.user_verification_code import UserVerificationCode # noqa
|
||||||
|
|
||||||
# this is the Alembic Config object, which provides
|
# this is the Alembic Config object, which provides
|
||||||
# access to the values within the .ini file in use.
|
# access to the values within the .ini file in use.
|
||||||
|
|
11
app/models/answer.py
Normal file
11
app/models/answer.py
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
from sqlalchemy import ForeignKey
|
||||||
|
from sqlalchemy.orm import Mapped, mapped_column
|
||||||
|
|
||||||
|
from app.database import Base
|
||||||
|
|
||||||
|
|
||||||
|
class Answer(Base):
|
||||||
|
__tablename__ = "answers"
|
||||||
|
|
||||||
|
self_id: Mapped[int] = mapped_column(ForeignKey("messages.id"), primary_key=True)
|
||||||
|
answer_id: Mapped[int] = mapped_column(ForeignKey("messages.id"))
|
|
@ -1,7 +1,5 @@
|
||||||
from datetime import datetime
|
from sqlalchemy import ForeignKey
|
||||||
|
from sqlalchemy.orm import mapped_column, Mapped
|
||||||
from sqlalchemy import func, ForeignKey, DateTime
|
|
||||||
from sqlalchemy.orm import mapped_column, Mapped, relationship
|
|
||||||
|
|
||||||
from app.database import Base
|
from app.database import Base
|
||||||
|
|
||||||
|
@ -14,82 +12,3 @@ class Chats(Base):
|
||||||
chat_for = mapped_column(ForeignKey("users.id"))
|
chat_for = mapped_column(ForeignKey("users.id"))
|
||||||
chat_name: Mapped[str]
|
chat_name: Mapped[str]
|
||||||
visibility: Mapped[bool] = mapped_column(server_default="true")
|
visibility: Mapped[bool] = mapped_column(server_default="true")
|
||||||
|
|
||||||
message = relationship("Messages", back_populates="chat")
|
|
||||||
usersxchats = relationship("UsersXChats", back_populates="chat")
|
|
||||||
user_to_exclude = relationship("Users", primaryjoin="Chats.chat_for == Users.id", back_populates="chat")
|
|
||||||
user_who_create = relationship("Users", primaryjoin="Chats.created_by == Users.id", back_populates="creator")
|
|
||||||
pinned_messages = relationship("PinnedMessages", back_populates="chat")
|
|
||||||
pinned_chats = relationship("PinnedChats", back_populates="chat")
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"Чат #{self.id}. Виден: {self.visibility}. Сделан {self.created_by} для {self.chat_for}"
|
|
||||||
|
|
||||||
|
|
||||||
class Messages(Base):
|
|
||||||
__tablename__ = "messages"
|
|
||||||
|
|
||||||
id: Mapped[int] = mapped_column(primary_key=True)
|
|
||||||
chat_id = mapped_column(ForeignKey("chats.id"))
|
|
||||||
user_id = mapped_column(ForeignKey("users.id"))
|
|
||||||
message: Mapped[str | None]
|
|
||||||
image_url: Mapped[str | None]
|
|
||||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
|
||||||
visibility: Mapped[bool] = mapped_column(server_default="true")
|
|
||||||
|
|
||||||
chat = relationship("Chats", back_populates="message")
|
|
||||||
user = relationship("Users", back_populates="message")
|
|
||||||
pinned_messages = relationship("PinnedMessages", back_populates="message")
|
|
||||||
self_id = relationship("Answers", primaryjoin="Messages.id == Answers.self_id", back_populates="self_message")
|
|
||||||
answer_id = relationship("Answers", primaryjoin="Messages.id == Answers.answer_id", back_populates="answer_message")
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"#{self.id} {self.message} от {self.user_id}. Написано {self.created_at}"
|
|
||||||
|
|
||||||
|
|
||||||
class Answers(Base):
|
|
||||||
__tablename__ = "answers"
|
|
||||||
|
|
||||||
self_id: Mapped[int] = mapped_column(ForeignKey("messages.id"), primary_key=True)
|
|
||||||
answer_id: Mapped[int] = mapped_column(ForeignKey("messages.id"))
|
|
||||||
|
|
||||||
self_message = relationship("Messages", primaryjoin="Answers.self_id == Messages.id", back_populates="self_id")
|
|
||||||
answer_message = relationship("Messages", primaryjoin="Answers.answer_id == Messages.id", back_populates="answer_id")
|
|
||||||
|
|
||||||
|
|
||||||
class UsersXChats(Base):
|
|
||||||
__tablename__ = "usersxchats"
|
|
||||||
|
|
||||||
id: Mapped[int] = mapped_column(primary_key=True)
|
|
||||||
user_id = mapped_column(ForeignKey("users.id"))
|
|
||||||
chat_id = mapped_column(ForeignKey("chats.id"))
|
|
||||||
|
|
||||||
chat = relationship("Chats", back_populates="usersxchats")
|
|
||||||
user = relationship("Users", back_populates="usersxchats")
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"Юзер #{self.user_id} допущен к чату {self.chat_id}"
|
|
||||||
|
|
||||||
|
|
||||||
class PinnedMessages(Base):
|
|
||||||
__tablename__ = "pinnedmessages"
|
|
||||||
|
|
||||||
id: Mapped[int] = mapped_column(primary_key=True)
|
|
||||||
chat_id = mapped_column(ForeignKey("chats.id"))
|
|
||||||
message_id = mapped_column(ForeignKey("messages.id"))
|
|
||||||
user_id = mapped_column(ForeignKey("users.id"))
|
|
||||||
|
|
||||||
chat = relationship("Chats", back_populates="pinned_messages")
|
|
||||||
message = relationship("Messages", back_populates="pinned_messages")
|
|
||||||
user = relationship("Users", back_populates="pinned_messages")
|
|
||||||
|
|
||||||
|
|
||||||
class PinnedChats(Base):
|
|
||||||
__tablename__ = "pinnedchats"
|
|
||||||
|
|
||||||
id: Mapped[int] = mapped_column(primary_key=True)
|
|
||||||
user_id = mapped_column(ForeignKey("users.id"))
|
|
||||||
chat_id = mapped_column(ForeignKey("chats.id"))
|
|
||||||
|
|
||||||
chat = relationship("Chats", back_populates="pinned_chats")
|
|
||||||
user = relationship("Users", back_populates="pinned_chats")
|
|
||||||
|
|
18
app/models/message.py
Normal file
18
app/models/message.py
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
from sqlalchemy import ForeignKey, func, DateTime
|
||||||
|
from sqlalchemy.orm import Mapped, mapped_column
|
||||||
|
|
||||||
|
from app.database import Base
|
||||||
|
|
||||||
|
|
||||||
|
class Message(Base):
|
||||||
|
__tablename__ = "messages"
|
||||||
|
|
||||||
|
id: Mapped[int] = mapped_column(primary_key=True)
|
||||||
|
chat_id = mapped_column(ForeignKey("chats.id"))
|
||||||
|
user_id = mapped_column(ForeignKey("users.id"))
|
||||||
|
message: Mapped[str | None]
|
||||||
|
image_url: Mapped[str | None]
|
||||||
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||||
|
visibility: Mapped[bool] = mapped_column(server_default="true")
|
12
app/models/pinned_chat.py
Normal file
12
app/models/pinned_chat.py
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
from sqlalchemy import ForeignKey
|
||||||
|
from sqlalchemy.orm import Mapped, mapped_column
|
||||||
|
|
||||||
|
from app.database import Base
|
||||||
|
|
||||||
|
|
||||||
|
class PinnedChats(Base):
|
||||||
|
__tablename__ = "pinnedchats"
|
||||||
|
|
||||||
|
id: Mapped[int] = mapped_column(primary_key=True)
|
||||||
|
user_id = mapped_column(ForeignKey("users.id"))
|
||||||
|
chat_id = mapped_column(ForeignKey("chats.id"))
|
13
app/models/pinned_message.py
Normal file
13
app/models/pinned_message.py
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
from sqlalchemy import ForeignKey
|
||||||
|
from sqlalchemy.orm import Mapped, mapped_column
|
||||||
|
|
||||||
|
from app.database import Base
|
||||||
|
|
||||||
|
|
||||||
|
class PinnedMessages(Base):
|
||||||
|
__tablename__ = "pinnedmessages"
|
||||||
|
|
||||||
|
id: Mapped[int] = mapped_column(primary_key=True)
|
||||||
|
chat_id = mapped_column(ForeignKey("chats.id"))
|
||||||
|
message_id = mapped_column(ForeignKey("messages.id"))
|
||||||
|
user_id = mapped_column(ForeignKey("users.id"))
|
12
app/models/user_avatar.py
Normal file
12
app/models/user_avatar.py
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
from sqlalchemy import ForeignKey
|
||||||
|
from sqlalchemy.orm import Mapped, mapped_column
|
||||||
|
|
||||||
|
from app.database import Base
|
||||||
|
|
||||||
|
|
||||||
|
class UserAvatar(Base):
|
||||||
|
__tablename__ = "usersavatars"
|
||||||
|
|
||||||
|
id: Mapped[int] = mapped_column(primary_key=True)
|
||||||
|
user_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
|
||||||
|
avatar_image: Mapped[str]
|
12
app/models/user_chat.py
Normal file
12
app/models/user_chat.py
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
from sqlalchemy import ForeignKey
|
||||||
|
from sqlalchemy.orm import Mapped, mapped_column
|
||||||
|
|
||||||
|
from app.database import Base
|
||||||
|
|
||||||
|
|
||||||
|
class UserChat(Base):
|
||||||
|
__tablename__ = "usersxchats"
|
||||||
|
|
||||||
|
id: Mapped[int] = mapped_column(primary_key=True)
|
||||||
|
user_id = mapped_column(ForeignKey("users.id"))
|
||||||
|
chat_id = mapped_column(ForeignKey("chats.id"))
|
16
app/models/user_verification_code.py
Normal file
16
app/models/user_verification_code.py
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
from sqlalchemy import func, ForeignKey, DateTime
|
||||||
|
from sqlalchemy.orm import Mapped, mapped_column
|
||||||
|
|
||||||
|
from app.database import Base
|
||||||
|
|
||||||
|
|
||||||
|
class UserVerificationCode(Base):
|
||||||
|
__tablename__ = "usersverificationcodes"
|
||||||
|
|
||||||
|
id: Mapped[int] = mapped_column(primary_key=True)
|
||||||
|
user_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
|
||||||
|
code: Mapped[str]
|
||||||
|
description: Mapped[str]
|
||||||
|
date_of_creation: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
|
@ -1,7 +1,7 @@
|
||||||
from datetime import date, datetime
|
from datetime import date
|
||||||
|
|
||||||
from sqlalchemy import func, ForeignKey, DateTime
|
from sqlalchemy import func
|
||||||
from sqlalchemy.orm import mapped_column, Mapped, relationship
|
from sqlalchemy.orm import mapped_column, Mapped
|
||||||
|
|
||||||
from app.database import Base
|
from app.database import Base
|
||||||
|
|
||||||
|
@ -10,51 +10,12 @@ class Users(Base):
|
||||||
__tablename__ = "users"
|
__tablename__ = "users"
|
||||||
|
|
||||||
id: Mapped[int] = mapped_column(primary_key=True)
|
id: Mapped[int] = mapped_column(primary_key=True)
|
||||||
email: Mapped[str]
|
email: Mapped[str] = mapped_column(unique=True)
|
||||||
username: Mapped[str]
|
username: Mapped[str] = mapped_column(unique=True)
|
||||||
hashed_password: Mapped[str]
|
hashed_password: Mapped[str]
|
||||||
role: Mapped[int] = mapped_column(server_default="0")
|
role: Mapped[int] = mapped_column(server_default="0")
|
||||||
black_phoenix: Mapped[bool] = mapped_column(server_default="false")
|
black_phoenix: Mapped[bool] = mapped_column(server_default="false")
|
||||||
avatar_image: Mapped[str] = mapped_column(
|
avatar_image: Mapped[str] = mapped_column(server_default="https://images.black-phoenix.ru/static/images/%D1%82%D1%8B%20%D1%83%D0%B6%D0%B5%20%D0%BF%D0%B5%D1%88%D0%BA%D0%B0%20BP.png") # noqa: E501
|
||||||
server_default="https://images.black-phoenix.ru/static/images/%D1%82%D1%8B%20%D1%83%D0%B6%D0%B5%20%D0%BF%D0%B5%D1%88%D0%BA%D0%B0%20BP.png" # noqa: E501
|
|
||||||
)
|
|
||||||
avatar_hex: Mapped[str] = mapped_column(server_default="#30293f")
|
avatar_hex: Mapped[str] = mapped_column(server_default="#30293f")
|
||||||
date_of_birth: Mapped[date]
|
date_of_birth: Mapped[date]
|
||||||
date_of_registration: Mapped[date] = mapped_column(server_default=func.now())
|
date_of_registration: Mapped[date] = mapped_column(server_default=func.now())
|
||||||
|
|
||||||
message = relationship("Messages", back_populates="user")
|
|
||||||
usersxchats = relationship("UsersXChats", back_populates="user")
|
|
||||||
chat = relationship("Chats", primaryjoin="Chats.chat_for == Users.id", back_populates="user_to_exclude")
|
|
||||||
creator = relationship("Chats", primaryjoin="Chats.created_by == Users.id", back_populates="user_who_create")
|
|
||||||
verificationcode = relationship("UsersVerificationCodes", back_populates="user")
|
|
||||||
pinned_messages = relationship("PinnedMessages", back_populates="user")
|
|
||||||
pinned_chats = relationship("PinnedChats", back_populates="user")
|
|
||||||
avatars = relationship("UsersAvatars", back_populates="user")
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"Юзер {self.username}"
|
|
||||||
|
|
||||||
|
|
||||||
class UsersVerificationCodes(Base):
|
|
||||||
__tablename__ = "usersverificationcodes"
|
|
||||||
|
|
||||||
id: Mapped[int] = mapped_column(primary_key=True)
|
|
||||||
user_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
|
|
||||||
code: Mapped[str]
|
|
||||||
description: Mapped[str]
|
|
||||||
date_of_creation: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
|
||||||
|
|
||||||
user = relationship("Users", back_populates="verificationcode")
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"Код {self.code} для юзера {self.user_id}. {self.description}"
|
|
||||||
|
|
||||||
|
|
||||||
class UsersAvatars(Base):
|
|
||||||
__tablename__ = "usersavatars"
|
|
||||||
|
|
||||||
id: Mapped[int] = mapped_column(primary_key=True)
|
|
||||||
user_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
|
|
||||||
avatar_image: Mapped[str]
|
|
||||||
|
|
||||||
user = relationship("Users", back_populates="avatars")
|
|
||||||
|
|
|
@ -7,8 +7,11 @@ from httpx import AsyncClient
|
||||||
|
|
||||||
from app.config import settings
|
from app.config import settings
|
||||||
from app.database import Base, async_session_maker, engine
|
from app.database import Base, async_session_maker, engine
|
||||||
from app.models.chat import Users, UsersVerificationCodes
|
from app.models.users import Users
|
||||||
from app.models.chat import Chats, UsersXChats, Messages
|
from app.models.user_verification_code import UserVerificationCode
|
||||||
|
from app.models.chat import Chats
|
||||||
|
from app.models.message import Message
|
||||||
|
from app.models.user_chat import UserChat
|
||||||
from app.main import app as fastapi_app
|
from app.main import app as fastapi_app
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,10 +41,10 @@ async def prepare_database():
|
||||||
|
|
||||||
async with async_session_maker() as session:
|
async with async_session_maker() as session:
|
||||||
add_users = insert(Users).values(new_users)
|
add_users = insert(Users).values(new_users)
|
||||||
add_users_verification_codes = insert(UsersVerificationCodes).values(users_verification_codes)
|
add_users_verification_codes = insert(UserVerificationCode).values(users_verification_codes)
|
||||||
add_chats = insert(Chats).values(chats)
|
add_chats = insert(Chats).values(chats)
|
||||||
add_users_x_chats = insert(UsersXChats).values(users_x_chats)
|
add_users_x_chats = insert(UserChat).values(users_x_chats)
|
||||||
add_messages = insert(Messages).values(messages)
|
add_messages = insert(Message).values(messages)
|
||||||
set_verified_user = update(Users).values(role=1).where(Users.id == 3)
|
set_verified_user = update(Users).values(role=1).where(Users.id == 3)
|
||||||
|
|
||||||
await session.execute(add_users)
|
await session.execute(add_users)
|
||||||
|
|
|
@ -2,8 +2,11 @@ from sqlalchemy import update, select, insert, and_, func, text, delete
|
||||||
|
|
||||||
from app.dao.base import BaseDAO
|
from app.dao.base import BaseDAO
|
||||||
from app.database import async_session_maker, engine # noqa
|
from app.database import async_session_maker, engine # noqa
|
||||||
from app.models.chat import UsersXChats, Chats
|
from app.models.chat import Chats
|
||||||
from app.models.users import Users, UsersVerificationCodes, UsersAvatars
|
from app.models.user_avatar import UserAvatar
|
||||||
|
from app.models.users import Users
|
||||||
|
from app.models.user_verification_code import UserVerificationCode
|
||||||
|
from app.models.user_chat import UserChat
|
||||||
from app.users.schemas import SUser, SUserAvatars
|
from app.users.schemas import SUser, SUserAvatars
|
||||||
|
|
||||||
|
|
||||||
|
@ -63,9 +66,9 @@ class UserDAO(BaseDAO):
|
||||||
WHERE user_id = 1
|
WHERE user_id = 1
|
||||||
"""
|
"""
|
||||||
chats_with_descriptions = (
|
chats_with_descriptions = (
|
||||||
select(UsersXChats.__table__.columns, Chats.__table__.columns)
|
select(UserChat.__table__.columns, Chats.__table__.columns)
|
||||||
.select_from(UsersXChats)
|
.select_from(UserChat)
|
||||||
.join(Chats, UsersXChats.chat_id == Chats.id)
|
.join(Chats, UserChat.chat_id == Chats.id)
|
||||||
).cte("chats_with_descriptions")
|
).cte("chats_with_descriptions")
|
||||||
|
|
||||||
chats_with_avatars = (
|
chats_with_avatars = (
|
||||||
|
@ -108,7 +111,7 @@ class UserDAO(BaseDAO):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def add_user_avatar(user_id: int, avatar: str) -> bool:
|
async def add_user_avatar(user_id: int, avatar: str) -> bool:
|
||||||
query = insert(UsersAvatars).values(user_id=user_id, avatar_image=avatar)
|
query = insert(UserAvatar).values(user_id=user_id, avatar_image=avatar)
|
||||||
async with async_session_maker() as session:
|
async with async_session_maker() as session:
|
||||||
await session.execute(query)
|
await session.execute(query)
|
||||||
await session.commit()
|
await session.commit()
|
||||||
|
@ -121,11 +124,11 @@ class UserDAO(BaseDAO):
|
||||||
"user_avatars", select(
|
"user_avatars", select(
|
||||||
func.json_agg(
|
func.json_agg(
|
||||||
func.json_build_object(
|
func.json_build_object(
|
||||||
"avatar_url", UsersAvatars.avatar_image
|
"avatar_url", UserAvatar.avatar_image
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.where(UsersAvatars.user_id == user_id)
|
.where(UserAvatar.user_id == user_id)
|
||||||
.scalar_subquery()
|
.scalar_subquery()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -136,7 +139,7 @@ class UserDAO(BaseDAO):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def delete_user_avatar(avatar_id: int, user_id: int) -> bool:
|
async def delete_user_avatar(avatar_id: int, user_id: int) -> bool:
|
||||||
query = delete(UsersAvatars).where(and_(UsersAvatars.id == avatar_id, UsersAvatars.user_id == user_id))
|
query = delete(UserAvatar).where(and_(UserAvatar.id == avatar_id, UserAvatar.user_id == user_id))
|
||||||
async with async_session_maker() as session:
|
async with async_session_maker() as session:
|
||||||
await session.execute(query)
|
await session.execute(query)
|
||||||
await session.commit()
|
await session.commit()
|
||||||
|
@ -144,12 +147,12 @@ class UserDAO(BaseDAO):
|
||||||
|
|
||||||
|
|
||||||
class UserCodesDAO(BaseDAO):
|
class UserCodesDAO(BaseDAO):
|
||||||
model = UsersVerificationCodes
|
model = UserVerificationCode
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def set_user_codes(cls, user_id: int, code: str, description: str):
|
async def set_user_codes(cls, user_id: int, code: str, description: str):
|
||||||
query = (
|
query = (
|
||||||
insert(UsersVerificationCodes)
|
insert(UserVerificationCode)
|
||||||
.values(user_id=user_id, code=code, description=description)
|
.values(user_id=user_id, code=code, description=description)
|
||||||
.returning(cls.model.code)
|
.returning(cls.model.code)
|
||||||
)
|
)
|
||||||
|
@ -173,8 +176,8 @@ class UserCodesDAO(BaseDAO):
|
||||||
AND now() - usersverificationcodes.date_of_creation < INTERVAL '30 minutes'
|
AND now() - usersverificationcodes.date_of_creation < INTERVAL '30 minutes'
|
||||||
"""
|
"""
|
||||||
query = (
|
query = (
|
||||||
select(UsersVerificationCodes.__table__.columns)
|
select(UserVerificationCode.__table__.columns)
|
||||||
.where((func.now() - UsersVerificationCodes.date_of_creation) < text("INTERVAL '10 minutes'"))
|
.where((func.now() - UserVerificationCode.date_of_creation) < text("INTERVAL '10 minutes'"))
|
||||||
.filter_by(**filter_by)
|
.filter_by(**filter_by)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue