I am currently in the process of writing a system application that will be operated by multiple users. This will require individual users to access the application while limiting access to those that shouldn't be using it. The application will have several areas of access, which all users will not have access to. At this time, it may change in the future, the application is more or less a proof of concept and will be storing user information in a DB.
What I have here is what I'm calling the Operator Library. This part of my code is strictly how to access the portion of the DB that interacts with the users table. There will be other libraries that will be written to access the DB related to specific tables in a very similar manner to the below.
UPDATE:
looking at the documentation, it seems they recommend using a with statement for handling opening and using individual sessions. I've also added some simple exception handling.
Anything else I should be adding?
DBOperatorLibary.py
from Models import Operator, engine
from sqlalchemy.orm import sessionmaker
local_session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
def create_operator(username, password, privilage):
ret = None
with local_session() as session:
operator = Operator(username=username, privilage=privilage)
if operator.password == "":
operator.password = password
session.add(operator)
try:
session.commit()
session.refresh(operator)
ret = operator
except Exception as e:
ret = e.args
return ret
def get_operators():
with local_session() as session:
operators = session.query(Operator).all()
return operators
def update_operator(operator_id, username, password, privilage):
ret = None
with local_session() as session:
operator = session.query(Operator).get(operator_id)
operator.username = username
operator.password = password
operator.privilage = privilage
try:
session.commit()
session.refresh(operator)
ret = operator
except Exception as e:
ret = e.args
return ret
def delete_operator(operator_id):
ret = None
with local_session() as session:
operator = session.query(Operator).get(operator_id)
session.delete(operator)
try:
session.commit()
ret = operator
except Exception as e:
ret = e.args
return ret
def validate_operator_password(username, password):
with local_session() as session:
operator = (
session.query(Operator)
.filter(Operator.username == username)
.first()
)
if operator is None:
return False
return operator.check_password(password)
if __name__ == "__main__":
...
Models.py
from BaseModel import Base
from OperatorModel import Operator
from RecordModels import Record
from sqlalchemy import create_engine
engine = create_engine("sqlite:///db/application.db", echo=True)
Base.metadata.create_all(bind=engine)
BaseModel.py
from sqlalchemy.orm import DeclarativeBase, MappedAsDataclass
class Base(MappedAsDataclass, DeclarativeBase):
"""subclasses will be converted to dataclasses"""
OperatorModel.py
from datetime import datetime
from BaseModel import Base
from sqlalchemy import func
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import Mapped, mapped_column
from werkzeug.security import check_password_hash, generate_password_hash
class Operator(Base):
__tablename__ = "operators"
oid: Mapped[int] = mapped_column(primary_key=True, init=False)
created_on: Mapped[datetime] = mapped_column(
init=False, server_default=func.now()
)
username: Mapped[str]
privilage: Mapped[str]
_password: Mapped[str] = ""
@hybrid_property
def password(self):
return self._password
@password.setter
def password(self, password):
self._password = generate_password_hash(password)
return self._password
def check_password(self, password):
return check_password_hash(self._password, password)
def __repr__(self):
return f"User Record {self.oid}\
\n\tUsername: {self.username} \
\n\tPrivilage: {self.privilage} \
\n\tCreated On: {self.created_on}"