new database system

This commit is contained in:
Bedir Tuğra Karaabalı 2025-05-14 16:31:46 +03:00
parent 039b877241
commit bf71979982
8 changed files with 92 additions and 124 deletions

View File

@ -1,23 +0,0 @@
from fastapi import HTTPException
from sqlalchemy import Column, Integer, String, Float, Boolean, ForeignKey
from sqlalchemy.dialects.postgresql import ARRAY
from sqlalchemy.orm import Session, relationship
from ..config import Base
'''
##### veri tabanı modelleri #####
class Collections(Base):
__tablename__ = "collections_table"
collection_id = Column(Integer, index=True, primary_key=True , autoincrement=True)
user_id = Column(Integer, ForeignKey('users_table.user_id'), nullable=False)
visibility = Column(Boolean, default=True)
colllection_name = Column(String, default="No name")
collection_description = Column(String, default="No description")
# ilişkiler
user = relationship("DBUser", back_populates="user_collections")
items = relationship("Items", back_populates="collection", cascade="all, delete-orphan")
'''

View File

@ -1,21 +1,22 @@
from enum import Enum from enum import Enum
import random import random
import smtplib import smtplib
from backend.config import SECRET_KEY, ALGORITHM, ACCESS_TOKEN_EXPIRE_MINUTES ,pwd_context, get_session_db, Base from backend.config import SECRET_KEY, ALGORITHM, ACCESS_TOKEN_EXPIRE_MINUTES ,pwd_context, get_session_db, Base, user_collection
from datetime import datetime, timedelta, timezone from datetime import datetime, timedelta, timezone
from pydantic import BaseModel from pydantic import BaseModel
from fastapi import Depends, HTTPException from fastapi import Depends, HTTPException
from typing import Annotated from typing import Annotated
from fastapi.security import OAuth2PasswordBearer from fastapi.security import OAuth2PasswordBearer
from pydantic.networks import EmailStr from pydantic.networks import EmailStr
from sqlalchemy import Integer, DateTime from sqlalchemy import Integer, DateTime, ForeignKey
from sqlalchemy.orm import Session, relationship, mapped_column, Mapped from sqlalchemy.orm import Session, relationship, mapped_column, Mapped
from sqlalchemy.dialects.postgresql import ARRAY from sqlalchemy.dialects.postgresql import ARRAY
from email.message import EmailMessage from email.message import EmailMessage
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
if TYPE_CHECKING: if TYPE_CHECKING:
from ..items.models import Items from ..collectionObj.models import CollectionsDB #iç içe import döngüsünü önlemek için TYPE_CHECKING kullanıyoruz
import jwt import jwt
@ -66,6 +67,7 @@ class DBUser(Base):
__tablename__ = "users_table" __tablename__ = "users_table"
user_id: Mapped[int] = mapped_column(primary_key=True, index=True, autoincrement=True) user_id: Mapped[int] = mapped_column(primary_key=True, index=True, autoincrement=True)
#collection_id : Mapped[list[int]] = mapped_column(Integer, ForeignKey("collections_table.collection_id"), nullable=True) # collection_id ile ilişki
username : Mapped[str] = mapped_column(unique=True, index=True, nullable=False) username : Mapped[str] = mapped_column(unique=True, index=True, nullable=False)
email : Mapped[str] = mapped_column(unique=True, index=True, nullable=False) email : Mapped[str] = mapped_column(unique=True, index=True, nullable=False)
hashed_password : Mapped[str] = mapped_column(nullable=False) hashed_password : Mapped[str] = mapped_column(nullable=False)
@ -75,8 +77,13 @@ class DBUser(Base):
bio : Mapped[str] = mapped_column(default="No bio") bio : Mapped[str] = mapped_column(default="No bio")
follow_users : Mapped[list[int]] = mapped_column(ARRAY(Integer), default=[]) # takip edilen kullanıcılar follow_users : Mapped[list[int]] = mapped_column(ARRAY(Integer), default=[]) # takip edilen kullanıcılar
# -> buralar diğer tablolar ile olan ilişkiler # -> buralar diğer tablolar ile olan ilişkiler
items : Mapped[list['Items']] = relationship("Items", back_populates="user", cascade="all, delete-orphan") #items : Mapped[list['Items']] = relationship("Items", back_populates="user", cascade="all, delete-orphan") items'e direk değil collection üzerinden erişiyoruz
collections : Mapped[int] = mapped_column(default=0) # hat vermesin diye eklendi collections aktif değil collections : Mapped[list['CollectionsDB']] = relationship(
"CollectionsDB",
secondary=user_collection,
back_populates="users",
lazy='select'
) # collection'lar ile olan ilişki

42
collectionObj/models.py Normal file
View File

@ -0,0 +1,42 @@
from fastapi import HTTPException
from sqlalchemy import Column, Integer, String, Float, Boolean, ForeignKey
from sqlalchemy.dialects.postgresql import ARRAY
from sqlalchemy.orm import Session, relationship, mapped_column, Mapped
from ..config import Base, get_session_db, user_collection, collection_item
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from ..auth.models import DBUser
from ..items.models import Items
##### veri tabanı modelleri #####
class CollectionsDB(Base):
__tablename__ = "collections_table"
collection_id : Mapped[int] = mapped_column(Integer, primary_key=True)
#user_id : Mapped[int] = mapped_column(Integer, ForeignKey("users_table.user_id"), nullable=False) # user_id ile ilişki
#item_id : Mapped[list[int]] = mapped_column(Integer, ForeignKey("items_table.item_id"), nullable=False) # item_id ile ilişki
visibility : Mapped[bool] = mapped_column(Boolean, default=True)
collection_name : Mapped[str] = mapped_column(String, nullable=False)
collection_description : Mapped[str] = mapped_column(String, default="No description")
# ilişkiler
users : Mapped['DBUser'] = relationship(
"DBUser",
secondary=user_collection,
back_populates="collections",
lazy='select'
) #back_populates karşı tarafın ismi
items : Mapped[list['Items']] = relationship(
"Items",
secondary=collection_item,
back_populates="collections" ,
lazy='select'
)
#### collection bir item listesi birde kullanıcı listesi tutacak

View File

@ -2,6 +2,7 @@ from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, DeclarativeBase from sqlalchemy.orm import sessionmaker, DeclarativeBase
from fastapi import FastAPI from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from sqlalchemy import Table, Column, Integer, String, Float, Boolean, ForeignKey
from passlib.context import CryptContext from passlib.context import CryptContext
from dotenv import load_dotenv from dotenv import load_dotenv
import os import os
@ -29,7 +30,7 @@ class Base(DeclarativeBase):
#models te içe aktarmayı unutma #models te içe aktarmayı unutma
def init_db(): def init_db():
#Base.metadata.drop_all(engine) # Veritabanını her başlangıcta siler burayada dikkat !!!!!!!! Base.metadata.drop_all(engine) # Veritabanını her başlangıcta siler burayada dikkat !!!!!!!!
Base.metadata.create_all(bind=engine) # Veritabanını oluşturur Base.metadata.create_all(bind=engine) # Veritabanını oluşturur
# Session dependency (FastAPI için) # Session dependency (FastAPI için)
@ -40,6 +41,21 @@ def get_session_db():
finally: finally:
db.close() db.close()
user_collection = Table( # user -> collection
"user_collection",
Base.metadata,
Column("user_id", Integer, ForeignKey("users_table.user_id"), primary_key=True),
Column("collection_id", Integer, ForeignKey("collections_table.collection_id"), primary_key=True),
)
collection_item = Table( # collection -> item
"collection_item",
Base.metadata,
Column("collection_id", ForeignKey("collections_table.collection_id"), primary_key=True),
Column("item_id", ForeignKey("items_table.item_id"), primary_key=True)
)
### SECRET KEY ### ### SECRET KEY ###

View File

@ -4,11 +4,12 @@ from sqlalchemy import DateTime
from pydantic import BaseModel from pydantic import BaseModel
from fastapi import Depends from fastapi import Depends
from sqlalchemy.orm import Session, relationship, mapped_column, Mapped from sqlalchemy.orm import Session, relationship, mapped_column, Mapped
from sqlalchemy import ForeignKey, Column, Integer, String, Float from sqlalchemy import String, Float, Integer, ForeignKey
from sqlalchemy.dialects.postgresql import ARRAY from sqlalchemy.dialects.postgresql import ARRAY
from ..config import Base, get_session_db from ..config import Base, get_session_db, collection_item
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from ..auth.models import Role, Status, UserBase, DBUser from ..auth.models import Role, Status, UserBase
from ..collectionObj.models import CollectionsDB
class UserProfileBase(UserBase): class UserProfileBase(UserBase):
@ -56,61 +57,23 @@ class Item(BaseItem):
# Tüm modeller AUTH'da veri tabanına işlendi yukardaki # Tüm modeller AUTH'da veri tabanına işlendi yukardaki
#modeller veri tabanında mevcuttur. Değiştirmek için AUTH'daki #modeller veri tabanında mevcuttur. Değiştirmek için AUTH'daki
# DBUser modelini değiştirip tekrar veri tabanına işleyebilirsin # DBUser modelini değiştirip tekrar veri tabanına işleyebilirsin
'''
'''
class Items(Base): class Items(Base):
__tablename__ = "items_table" __tablename__ = "items_table"
item_id : Mapped[int] = mapped_column(primary_key=True, index=True, autoincrement=True) item_id : Mapped[int] = mapped_column(primary_key=True, index=True, autoincrement=True)
user_id : Mapped[int] = mapped_column(ForeignKey('users_table.user_id'), nullable=False, index=True) #collection_id : Mapped[list[int]] = mapped_column(Integer, ForeignKey("collections_table.collection_id"), nullable=True) # collection_id ile ilişki
item_created_date : Mapped[datetime] = mapped_column(DateTime, default=datetime.now()) item_created_date : Mapped[datetime] = mapped_column(DateTime, default=datetime.now())
item_location = Column(String, default="No location") item_location: Mapped[str] = mapped_column(String, default="No location")
item_type = Column(String, default="No type") item_type: Mapped[str] = mapped_column(String, default="No type")
item_content = Column(String, default="No content") item_content: Mapped[str] = mapped_column(String, default="No content")
item_score = Column(Float, default=0.0) item_score: Mapped[float] = mapped_column(Float, default=0.0)
# ilişkiler # ilişkiler
collections : Mapped['CollectionsDB']= relationship(
"CollectionsDB",
secondary=collection_item,
back_populates="items",
lazy='select'
) #back_populates karşı tarafın ismi
user : Mapped['DBUser'] = relationship("DBUser", back_populates="items", lazy='select')
#collection = relationship("Collections", back_populates="items")
'''
'''
def is_user_exsist_get(username : str, session : Annotated[Session, Depends(get_session_db)]) -> bool | UserProfilePrivate:
#DBUser veritabanındaki nesnedir her niteliğe sahiptir
user = session.query(DBUser).filter(DBUser.username == username).first()
return user
def all_users(session: Annotated[Session, Depends(get_session_db)]) -> list[UserProfilePrivate]:
users = session.query(DBUser).all()
return [UserProfilePrivate(
username=user.username,
bio=user.bio,
created_date=user.created_date,
items = [Item.model_validate(item) for item in user.items],
collections=user.collections,
role=user.role,
status=user.status
) for user in users]
def add_Item_user(
user: Annotated[UserProfileID, Depends(get_session_db)],
session: Annotated[Session, Depends(get_session_db)],
item: ItemCreate) -> bool:
# DBUser veritabanındaki nesnedir her niteliğe sahiptir
item = Items(
user_id=user.user_id,
item_location=item.item_location,
item_type=item.item_type,
item_content=item.item_content,
item_created_date=item.item_created_date
)
session.add(item)
session.commit()
return True

View File

@ -1,4 +1,4 @@
from .models import ItemCreate, UserProfileBase, UserProfileID, UserProfilePrivate, UserProfilePublic, add_Item_user, all_users, is_user_exsist_get from .models import ItemCreate, UserProfileBase, UserProfileID, UserProfilePrivate, UserProfilePublic
from fastapi import APIRouter, Depends from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from ..config import get_session_db from ..config import get_session_db
@ -12,44 +12,7 @@ router = APIRouter(
dependencies=[], dependencies=[],
) )
@router.get('/all_profiles') #tüm crud işlemleri yeni veri tabanı modeli ile yapılacak
async def get_user_profile(session: Annotated[Session, Depends(get_session_db)]) -> list[UserProfilePrivate]:
return all_users(session=session)
@router.get('/profile/{username}')
async def get_user_profile_by_username(
username: str,
session: Annotated[Session, Depends(get_session_db)],
) -> UserProfilePublic | dict:
user : UserProfilePublic = is_user_exsist_get(username, session)
if user is None:
return {"error": "User not found"}
return user
@router.get('/profile/me')
async def get_user_profile_me(
current_user: Annotated[UserProfilePrivate, Depends(get_current_active_user)],
session : Annotated[Session, Depends(get_session_db)], #dependtek kaynaklı UserPublic doner
) -> UserProfilePrivate:
return is_user_exsist_get(current_user.username, session)
@router.post('/create')
async def create_user_profile(
user : Annotated[UserProfileID, Depends(get_current_active_user)],
session: Annotated[Session, Depends(get_session_db)],
item : Annotated[ItemCreate , None] = None
) -> dict:
if add_Item_user(user, session, item) :
return {"message": "User item created successfully"}
return {"error": "User item creation failed"}

View File

@ -1,7 +1,7 @@
from .config import app from .config import app
from .auth.router import router as auth_router from .auth.router import router as auth_router
from .items.router import router as items_router from .items.router import router as items_router
from ._collections.router import router as collections_router from .collectionObj.router import router as collections_router
app.include_router(auth_router) app.include_router(auth_router)
app.include_router(collections_router) app.include_router(collections_router)