Files
scrapAPI/app/models.py

192 lines
7.0 KiB
Python

from sqlalchemy import Column, Integer, String, Float, DateTime, ForeignKey, Text
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import as_declarative, declared_attr
from sqlalchemy.sql import func
from pydantic import BaseModel
from typing import Optional, List
@as_declarative()
class Base:
@declared_attr
def __tablename__(cls):
return cls.__name__.lower()
# Automatically apply nullable=False to ForeignKey columns unless explicitly set
@staticmethod
def Column(*args, **kwargs):
if any(isinstance(arg, ForeignKey) for arg in args) and 'nullable' not in kwargs:
kwargs['nullable'] = False
return Column(*args, **kwargs)
# Enum for User Role
from sqlalchemy import Enum
from enum import Enum as PyEnum
class UserRole(PyEnum):
PRIVATE = "PRIVATE"
BUSINESS = "BUSINESS"
# User model
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String, nullable=False)
company = Column(String, nullable=True)
address = Column(String, nullable=False)
postcode = Column(Integer, nullable=False)
city = Column(String, nullable=False)
latitude = Column(String, nullable=True)
longitude = Column(String, nullable=True)
phone = Column(String, nullable=False)
privatePhone = Column(String, nullable=True)
email = Column(String, unique=True, nullable=False)
cvr = Column(String, nullable=True)
password = Column(String, nullable=False)
role = Column(Enum(UserRole), default=UserRole.PRIVATE)
updatedAt = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
createdAt = Column(DateTime(timezone=True), server_default=func.now())
auctions = relationship('Auction', back_populates='user')
accounts = relationship('Account', back_populates='user')
sessions = relationship('Session', back_populates='user')
bids = relationship('Bid', back_populates='user')
# Vehicle model
class Vehicle(Base):
__tablename__ = 'vehicles'
id = Column(Integer, primary_key=True, autoincrement=True)
brand = Column(String, nullable=False)
model = Column(String, nullable=False)
variant = Column(String, nullable=True)
year = Column(Integer, nullable=False)
kilometers = Column(Integer, nullable=False)
condition = Column(String, nullable=False)
location = Column(String, nullable=False)
latitude = Column(String, nullable=True)
longitude = Column(String, nullable=True)
gasType = Column(String, nullable=False)
images = Column(Text, nullable=False) # Store image paths or references
description = Column(String, nullable=False)
service = Column(String, nullable=False)
inspectedAt = Column(DateTime(timezone=True), nullable=True)
updatedAt = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
createdAt = Column(DateTime(timezone=True), server_default=func.now())
auctions = relationship('Auction', back_populates='vehicle')
equipment = relationship('VehicleEquipment', back_populates='vehicle')
# Equipment model
class Equipment(Base):
__tablename__ = 'equipment'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String, nullable=False)
vehicles = relationship('VehicleEquipment', back_populates='equipment')
# Vehicle-Equipment association table
class VehicleEquipment(Base):
__tablename__ = 'vehicle_equipment'
vehicle_id = Column(Integer, ForeignKey('vehicles.id'), primary_key=True)
equipment_id = Column(Integer, ForeignKey('equipment.id'), primary_key=True)
vehicle = relationship('Vehicle', back_populates='equipment')
equipment = relationship('Equipment', back_populates='vehicles')
# Auction model
class Auction(Base):
__tablename__ = 'auctions'
id = Column(Integer, primary_key=True, autoincrement=True)
vehicleId = Column(Integer, ForeignKey('vehicles.id'), nullable=False)
userId = Column(Integer, ForeignKey('users.id'), nullable=False)
askingPrice = Column(Float, nullable=False)
description = Column(String, nullable=True)
updatedAt = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
createdAt = Column(DateTime(timezone=True), server_default=func.now())
user = relationship('User', back_populates='auctions')
vehicle = relationship('Vehicle', back_populates='auctions')
bids = relationship('Bid', back_populates='auction')
# Bid model
class Bid(Base):
__tablename__ = 'bids'
id = Column(Integer, primary_key=True, autoincrement=True)
auctionId = Column(Integer, ForeignKey('auctions.id'), nullable=False)
userId = Column(Integer, ForeignKey('users.id'), nullable=False)
bid = Column(Float, nullable=False)
updatedAt = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
createdAt = Column(DateTime(timezone=True), server_default=func.now())
auction = relationship('Auction', back_populates='bids')
user = relationship('User', back_populates='bids')
# Account model
class Account(Base):
__tablename__ = 'accounts'
id = Column(Integer, primary_key=True, autoincrement=True)
userId = Column(Integer, ForeignKey('users.id'), nullable=False)
type = Column(String, nullable=False)
provider = Column(String, nullable=False)
providerAccountId = Column(String, nullable=False)
refresh_token = Column(String, nullable=True)
access_token = Column(String, nullable=True)
expires_at = Column(Integer, nullable=True)
user = relationship('User', back_populates='accounts')
# Session model
class Session(Base):
__tablename__ = 'sessions'
id = Column(Integer, primary_key=True, autoincrement=True)
sessionToken = Column(String, unique=True, nullable=False)
userId = Column(Integer, ForeignKey('users.id'))
expires = Column(DateTime, nullable=False)
user = relationship('User', back_populates='sessions')
# VerificationToken model
class VerificationToken(Base):
__tablename__ = 'verification_tokens'
identifier = Column(String, primary_key=True)
token = Column(String, unique=True, nullable=False)
expires = Column(DateTime, nullable=False)
# Pydantic model for user registration
class UserCreate(BaseModel):
email: str
password: str
name: str
phone: str
address: str
postcode: int
city: str
role: str
company: Optional[str] = None
privatePhone: Optional[str] = None
cvr: Optional[str] = None
class UserLogin(BaseModel):
email: str
password: str
class VehicleCreate(BaseModel):
brand: str
model: str
variant: Optional[str]
year: int
kilometers: int
condition: str
location: str
latitude: Optional[float]
longitude: Optional[float]
gasType: str
images: str
description: str
service: str
inspectedAt: Optional[str] # ISO format for datetime
equipment_ids: List[int] # List of equipment IDs
class AuctionCreate(BaseModel):
askingPrice: float
description: Optional[str]
vehicle: VehicleCreate