feat: use Mapped syntax for columns
This commit is contained in:
parent
cb70f17ad5
commit
6397bd1316
9 changed files with 108 additions and 105 deletions
|
|
@ -5,30 +5,30 @@ Models:
|
|||
- Contact: id[pk], email, first_name, last_name, phonenumber, vat_number
|
||||
street_address, street_address_line_2, post_office_box_number, address_locality, country_code, address_region, postal_code
|
||||
"""
|
||||
from sqlalchemy import ForeignKey
|
||||
from sqlalchemy.orm import mapped_column, Mapped
|
||||
|
||||
from sqlalchemy import Column, Integer, String, ForeignKey
|
||||
|
||||
from src.database import Base
|
||||
from src.models import CustomBase
|
||||
|
||||
|
||||
class Contact(Base):
|
||||
class Contact(CustomBase):
|
||||
__tablename__ = "contact"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
email = Column(String)
|
||||
first_name = Column(String)
|
||||
last_name = Column(String)
|
||||
phonenumber = Column(String)
|
||||
vat_number = Column(String, default=None, nullable=True)
|
||||
id: Mapped[int] = mapped_column(primary_key=True)
|
||||
email: Mapped[str]
|
||||
first_name: Mapped[str]
|
||||
last_name: Mapped[str]
|
||||
phonenumber: Mapped[str]
|
||||
vat_number: Mapped[str | None] = mapped_column(default=None)
|
||||
|
||||
street_address = Column(String)
|
||||
street_address_line_2 = Column(String)
|
||||
post_office_box_number = Column(String, default=None, nullable=True)
|
||||
locality = Column(String) # Ie City
|
||||
country_code = Column(String) # Eg GB
|
||||
address_region = Column(String, default=None, nullable=True)
|
||||
postal_code = Column(String)
|
||||
street_address : Mapped[str]
|
||||
street_address_line_2 : Mapped[str]
|
||||
post_office_box_number: Mapped[str | None] = mapped_column(default=None)
|
||||
locality : Mapped[str] # Ie City
|
||||
country_code : Mapped[str] # Eg GB
|
||||
address_region: Mapped[str | None] = mapped_column(default=None)
|
||||
postal_code : Mapped[str]
|
||||
|
||||
org_id = Column(
|
||||
Integer, ForeignKey("organisation.id", ondelete="CASCADE"), nullable=False
|
||||
org_id: Mapped[int] = mapped_column(
|
||||
ForeignKey("organisation.id", ondelete="CASCADE"), nullable=False
|
||||
)
|
||||
|
|
|
|||
|
|
@ -5,10 +5,9 @@ Exports:
|
|||
- db_dependency
|
||||
- Base (sqlalchemy base model)
|
||||
"""
|
||||
|
||||
from typing import Annotated
|
||||
from sqlalchemy import create_engine, StaticPool
|
||||
from sqlalchemy.orm import DeclarativeBase, sessionmaker, Session
|
||||
from sqlalchemy.orm import sessionmaker, Session
|
||||
|
||||
from fastapi import Depends
|
||||
|
||||
|
|
@ -41,7 +40,3 @@ def get_db():
|
|||
|
||||
|
||||
db_dependency = Annotated[Session, Depends(get_db)]
|
||||
|
||||
|
||||
class Base(DeclarativeBase):
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -18,20 +18,20 @@ Models:
|
|||
- org_id[FK][PK], user_id[FK][PK], group_id[FK][PK]
|
||||
"""
|
||||
|
||||
from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy import ForeignKey, UniqueConstraint
|
||||
from sqlalchemy.orm import relationship, mapped_column, Mapped
|
||||
|
||||
from src.database import Base
|
||||
from src.models import CustomBase
|
||||
|
||||
|
||||
class Permission(Base):
|
||||
class Permission(CustomBase):
|
||||
__tablename__ = "permission"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
resource = Column(String, nullable=False)
|
||||
action = Column(String, nullable=False)
|
||||
id: Mapped[int] = mapped_column(primary_key=True)
|
||||
resource: Mapped[str]
|
||||
action: Mapped[str]
|
||||
|
||||
service_id = Column(Integer, ForeignKey("service.id", ondelete="CASCADE"))
|
||||
service_id: Mapped[int] = mapped_column(ForeignKey("service.id", ondelete="CASCADE"))
|
||||
|
||||
__table_args__ = (
|
||||
UniqueConstraint(
|
||||
|
|
@ -46,10 +46,6 @@ class Permission(Base):
|
|||
"Service", back_populates="permission_rel", foreign_keys="Permission.service_id"
|
||||
)
|
||||
|
||||
@property
|
||||
def service_name(self):
|
||||
return self.service_rel.name
|
||||
|
||||
group_rel = relationship(
|
||||
"Group", secondary="group_permissions", back_populates="permission_rel"
|
||||
)
|
||||
|
|
@ -58,13 +54,17 @@ class Permission(Base):
|
|||
"Organisation", secondary="org_permissions", back_populates="permission_rel"
|
||||
)
|
||||
|
||||
@property
|
||||
def service_name(self):
|
||||
return self.service_rel.name
|
||||
|
||||
class Group(Base):
|
||||
|
||||
class Group(CustomBase):
|
||||
__tablename__ = "group"
|
||||
id = Column(Integer, primary_key=True)
|
||||
name = Column(String, nullable=False)
|
||||
id: Mapped[int] = mapped_column(primary_key=True)
|
||||
name: Mapped[str]
|
||||
|
||||
org_id = Column(Integer, ForeignKey("organisation.id", ondelete="CASCADE"))
|
||||
org_id: Mapped[int] = mapped_column(ForeignKey("organisation.id", ondelete="CASCADE"))
|
||||
|
||||
__table_args__ = (
|
||||
UniqueConstraint(
|
||||
|
|
@ -83,31 +83,31 @@ class Group(Base):
|
|||
)
|
||||
|
||||
|
||||
class GroupPermissions(Base):
|
||||
class GroupPermissions(CustomBase):
|
||||
__tablename__ = "group_permissions"
|
||||
group_id = Column(
|
||||
Integer, ForeignKey("group.id", ondelete="CASCADE"), primary_key=True
|
||||
group_id: Mapped[int] = mapped_column(
|
||||
ForeignKey("group.id", ondelete="CASCADE"), primary_key=True
|
||||
)
|
||||
permission_id = Column(
|
||||
Integer, ForeignKey("permission.id", ondelete="CASCADE"), primary_key=True
|
||||
permission_id: Mapped[int] = mapped_column(
|
||||
ForeignKey("permission.id", ondelete="CASCADE"), primary_key=True
|
||||
)
|
||||
|
||||
|
||||
class UserGroups(Base):
|
||||
class UserGroups(CustomBase):
|
||||
__tablename__ = "user_groups"
|
||||
user_id = Column(
|
||||
Integer, ForeignKey("user.id", ondelete="CASCADE"), primary_key=True
|
||||
user_id: Mapped[int] = mapped_column(
|
||||
ForeignKey("user.id", ondelete="CASCADE"), primary_key=True
|
||||
)
|
||||
group_id = Column(
|
||||
Integer, ForeignKey("group.id", ondelete="CASCADE"), primary_key=True
|
||||
group_id: Mapped[int] = mapped_column(
|
||||
ForeignKey("group.id", ondelete="CASCADE"), primary_key=True
|
||||
)
|
||||
|
||||
|
||||
class OrgPermissions(Base):
|
||||
class OrgPermissions(CustomBase):
|
||||
__tablename__ = "org_permissions"
|
||||
org_id = Column(
|
||||
Integer, ForeignKey("organisation.id", ondelete="CASCADE"), primary_key=True
|
||||
org_id: Mapped[int] = mapped_column(
|
||||
ForeignKey("organisation.id", ondelete="CASCADE"), primary_key=True
|
||||
)
|
||||
permission_id = Column(
|
||||
Integer, ForeignKey("permission.id", ondelete="CASCADE"), primary_key=True
|
||||
permission_id: Mapped[int] = mapped_column(
|
||||
ForeignKey("permission.id", ondelete="CASCADE"), primary_key=True
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,16 @@
|
|||
"""
|
||||
Global database models
|
||||
"""
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
from sqlalchemy import DateTime, JSON
|
||||
from sqlalchemy.orm import DeclarativeBase
|
||||
|
||||
|
||||
class CustomBase(DeclarativeBase):
|
||||
type_annotation_map = {
|
||||
datetime: DateTime(timezone=True),
|
||||
dict[str, Any]: JSON,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,26 +13,26 @@ Models:
|
|||
- owner_contact_rel: ORM relationship to Contact with owner_contact FK
|
||||
- OrgUsers: org_id[FK][PK], user_id[FK][PK]
|
||||
"""
|
||||
from typing import Any
|
||||
|
||||
from sqlalchemy import Column, Integer, String, ForeignKey, JSON
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy import ForeignKey
|
||||
from sqlalchemy.orm import relationship, Mapped, mapped_column
|
||||
|
||||
from src.database import Base
|
||||
from src.models import CustomBase
|
||||
|
||||
|
||||
class Organisation(Base):
|
||||
class Organisation(CustomBase):
|
||||
__tablename__ = "organisation"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
name = Column(String, unique=True)
|
||||
status = Column(String, default="partial")
|
||||
intake_questionnaire = Column(JSON)
|
||||
id: Mapped[int] = mapped_column(primary_key=True)
|
||||
name: Mapped[str]
|
||||
status: Mapped[str] = mapped_column(default="partial")
|
||||
intake_questionnaire: Mapped[dict[str, Any] | None]
|
||||
|
||||
root_user_id = Column(Integer, ForeignKey("user.id"))
|
||||
|
||||
billing_contact_id = Column(Integer, ForeignKey("contact.id"))
|
||||
security_contact_id = Column(Integer, ForeignKey("contact.id"))
|
||||
owner_contact_id = Column(Integer, ForeignKey("contact.id"))
|
||||
root_user_id: Mapped[int] = mapped_column(ForeignKey("user.id"))
|
||||
billing_contact_id: Mapped[int] = mapped_column(ForeignKey("contact.id"))
|
||||
security_contact_id: Mapped[int] = mapped_column(ForeignKey("contact.id"))
|
||||
owner_contact_id: Mapped[int] = mapped_column(ForeignKey("contact.id"))
|
||||
|
||||
user_rel = relationship(
|
||||
"User", secondary="orgusers", back_populates="organisation_rel"
|
||||
|
|
@ -41,10 +41,6 @@ class Organisation(Base):
|
|||
group_rel = relationship("Group", back_populates="org_rel")
|
||||
root_user_rel = relationship("User", foreign_keys="Organisation.root_user_id")
|
||||
|
||||
@property
|
||||
def root_user_email(self):
|
||||
return self.root_user_rel.email if self.root_user_rel else None
|
||||
|
||||
billing_contact_rel = relationship(
|
||||
"Contact", foreign_keys="Organisation.billing_contact_id"
|
||||
)
|
||||
|
|
@ -59,13 +55,14 @@ class Organisation(Base):
|
|||
"Permission", secondary="org_permissions", back_populates="org_rel"
|
||||
)
|
||||
|
||||
@property
|
||||
def root_user_email(self):
|
||||
return self.root_user_rel.email if self.root_user_rel else None
|
||||
|
||||
class OrgUsers(Base):
|
||||
class OrgUsers(CustomBase):
|
||||
__tablename__ = "orgusers"
|
||||
|
||||
org_id = Column(
|
||||
Integer, ForeignKey("organisation.id", ondelete="CASCADE"), primary_key=True
|
||||
)
|
||||
user_id = Column(
|
||||
Integer, ForeignKey("user.id", ondelete="CASCADE"), primary_key=True
|
||||
org_id: Mapped[int] = mapped_column(
|
||||
ForeignKey("organisation.id", ondelete="CASCADE"), primary_key=True
|
||||
)
|
||||
user_id: Mapped[int] = mapped_column(ForeignKey("user.id", ondelete="CASCADE"), primary_key=True)
|
||||
|
|
|
|||
|
|
@ -6,17 +6,16 @@ Models:
|
|||
- id[PK], name[U], api_key[U]
|
||||
"""
|
||||
|
||||
from sqlalchemy import Column, Integer, String
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.orm import relationship, mapped_column, Mapped
|
||||
|
||||
from src.database import Base
|
||||
from src.models import CustomBase
|
||||
|
||||
|
||||
class Service(Base):
|
||||
class Service(CustomBase):
|
||||
__tablename__ = "service"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
name = Column(String, unique=True)
|
||||
api_key = Column(String, unique=True)
|
||||
id: Mapped[int] = mapped_column(primary_key=True)
|
||||
name: Mapped[str] = mapped_column(unique=True)
|
||||
api_key: Mapped[str]
|
||||
|
||||
permission_rel = relationship("Permission", back_populates="service_rel")
|
||||
|
|
|
|||
|
|
@ -12,33 +12,32 @@ Models:
|
|||
|
||||
from collections import defaultdict
|
||||
|
||||
from sqlalchemy import Column, Integer, String
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.orm import relationship, mapped_column, Mapped
|
||||
|
||||
from src.database import Base
|
||||
from src.models import CustomBase
|
||||
|
||||
|
||||
class User(Base):
|
||||
class User(CustomBase):
|
||||
__tablename__ = "user"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
email = Column(String)
|
||||
first_name = Column(String)
|
||||
last_name = Column(String)
|
||||
oidc_id = Column(String, index=True, unique=True)
|
||||
id: Mapped[int] = mapped_column(primary_key=True)
|
||||
email: Mapped[str]
|
||||
first_name: Mapped[str]
|
||||
last_name: Mapped[str]
|
||||
oidc_id: Mapped[str] = mapped_column(index=True, unique=True)
|
||||
|
||||
organisation_rel = relationship(
|
||||
"Organisation", secondary="orgusers", back_populates="user_rel"
|
||||
)
|
||||
|
||||
@property
|
||||
def organisations(self):
|
||||
return [{"name": org.name, "id": org.id} for org in self.organisation_rel]
|
||||
|
||||
group_rel = relationship(
|
||||
"Group", secondary="user_groups", back_populates="user_rel"
|
||||
)
|
||||
|
||||
@property
|
||||
def organisations(self):
|
||||
return [{"name": org.name, "id": org.id} for org in self.organisation_rel]
|
||||
|
||||
@property
|
||||
def groups(self):
|
||||
result = defaultdict(list)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue