Before making a big mistake.

This commit is contained in:
Landon Wark
2023-11-16 14:55:55 -06:00
parent 6e865f1551
commit 74957ee318
22 changed files with 137 additions and 924 deletions

View File

@@ -1,5 +1,5 @@
'''
All database related operations.
'''
from .models import *
from .functions import *
from .models import *

View File

@@ -1,10 +1,10 @@
'''
Contains all models for sqlalchemy
'''
from .controls import Control, ControlType
# import order must go: orgs, kit, subs due to circular import issues
from .organizations import Organization, Contact
from .kits import KitType, ReagentType, Reagent, Discount, KitTypeReagentTypeAssociation, SubmissionType, SubmissionTypeKitTypeAssociation
from .submissions import (BasicSubmission, BacterialCulture, Wastewater, WastewaterArtic, WastewaterSample, BacterialCultureSample,
BasicSample, SubmissionSampleAssociation, WastewaterAssociation)
from tools import Base
from .controls import *
# import order must go: orgs, kit, subs due to circular import issues
from .organizations import *
from .kits import *
from .submissions import *

View File

@@ -7,7 +7,8 @@ from sqlalchemy.orm import relationship, Query
import logging
from operator import itemgetter
import json
from tools import Base, setup_lookup, query_return
from . import Base
from tools import setup_lookup, query_return
from datetime import date, datetime
from typing import List
from dateutil.parser import parse
@@ -19,7 +20,7 @@ class ControlType(Base):
Base class of a control archetype.
"""
__tablename__ = '_control_types'
__table_args__ = {'extend_existing': True}
id = Column(INTEGER, primary_key=True) #: primary key
name = Column(String(255), unique=True) #: controltype name (e.g. MCS)
@@ -58,6 +59,7 @@ class Control(Base):
"""
__tablename__ = '_control_samples'
__table_args__ = {'extend_existing': True}
id = Column(INTEGER, primary_key=True) #: primary key
parent_id = Column(String, ForeignKey("_control_types.id", name="fk_control_parent_id")) #: primary key of control type

View File

@@ -2,24 +2,31 @@
All kit and reagent related models
'''
from __future__ import annotations
from sqlalchemy import Column, String, TIMESTAMP, JSON, INTEGER, ForeignKey, Interval, Table, FLOAT, func
from sqlalchemy import Column, String, TIMESTAMP, JSON, INTEGER, ForeignKey, Interval, Table, FLOAT, func, BLOB
from sqlalchemy.orm import relationship, validates, Query
from sqlalchemy.ext.associationproxy import association_proxy
from datetime import date
import logging
from tools import check_authorization, Base, setup_lookup, query_return, Report, Result
from tools import check_authorization, setup_lookup, query_return, Report, Result
from typing import List
from . import Organization
from . import Base, Organization
logger = logging.getLogger(f'submissions.{__name__}')
reagenttypes_reagents = Table("_reagenttypes_reagents", Base.metadata, Column("reagent_id", INTEGER, ForeignKey("_reagents.id")), Column("reagenttype_id", INTEGER, ForeignKey("_reagent_types.id")))
reagenttypes_reagents = Table(
"_reagenttypes_reagents",
Base.metadata,
Column("reagent_id", INTEGER, ForeignKey("_reagents.id")),
Column("reagenttype_id", INTEGER, ForeignKey("_reagent_types.id")),
extend_existing = True
)
class KitType(Base):
"""
Base of kits used in submission processing
"""
__tablename__ = "_kits"
__table_args__ = {'extend_existing': True}
id = Column(INTEGER, primary_key=True) #: primary key
name = Column(String(64), unique=True) #: name of kit
@@ -162,6 +169,7 @@ class ReagentType(Base):
Base of reagent type abstract
"""
__tablename__ = "_reagent_types"
__table_args__ = {'extend_existing': True}
id = Column(INTEGER, primary_key=True) #: primary key
name = Column(String(64)) #: name of reagent type
@@ -251,6 +259,8 @@ class KitTypeReagentTypeAssociation(Base):
DOC: https://docs.sqlalchemy.org/en/14/orm/extensions/associationproxy.html
"""
__tablename__ = "_reagenttypes_kittypes"
__table_args__ = {'extend_existing': True}
reagent_types_id = Column(INTEGER, ForeignKey("_reagent_types.id"), primary_key=True)
kits_id = Column(INTEGER, ForeignKey("_kits.id"), primary_key=True)
uses = Column(JSON)
@@ -333,6 +343,7 @@ class Reagent(Base):
Concrete reagent instance
"""
__tablename__ = "_reagents"
__table_args__ = {'extend_existing': True}
id = Column(INTEGER, primary_key=True) #: primary key
type = relationship("ReagentType", back_populates="instances", secondary=reagenttypes_reagents) #: joined parent reagent type
@@ -491,6 +502,7 @@ class Discount(Base):
Relationship table for client labs for certain kits.
"""
__tablename__ = "_discounts"
__table_args__ = {'extend_existing': True}
id = Column(INTEGER, primary_key=True) #: primary key
kit = relationship("KitType") #: joined parent reagent type
@@ -558,12 +570,14 @@ class SubmissionType(Base):
Abstract of types of submissions.
"""
__tablename__ = "_submission_types"
__table_args__ = {'extend_existing': True}
id = Column(INTEGER, primary_key=True) #: primary key
name = Column(String(128), unique=True) #: name of submission type
info_map = Column(JSON) #: Where basic information is found in the excel workbook corresponding to this type.
instances = relationship("BasicSubmission", backref="submission_type")
# regex = Column(String(512))
template_file = Column(BLOB)
submissiontype_kit_associations = relationship(
"SubmissionTypeKitTypeAssociation",
@@ -619,6 +633,8 @@ class SubmissionTypeKitTypeAssociation(Base):
Abstract of relationship between kits and their submission type.
"""
__tablename__ = "_submissiontypes_kittypes"
__table_args__ = {'extend_existing': True}
submission_types_id = Column(INTEGER, ForeignKey("_submission_types.id"), primary_key=True)
kits_id = Column(INTEGER, ForeignKey("_kits.id"), primary_key=True)
mutable_cost_column = Column(FLOAT(2)) #: dollar amount per 96 well plate that can change with number of columns (reagents, tips, etc)

View File

@@ -4,20 +4,29 @@ All client organization related models.
from __future__ import annotations
from sqlalchemy import Column, String, INTEGER, ForeignKey, Table
from sqlalchemy.orm import relationship, Query
from tools import Base, check_authorization, setup_lookup, query_return
from . import Base
from tools import check_authorization, setup_lookup, query_return
from typing import List
import logging
logger = logging.getLogger(f"submissions.{__name__}")
# table containing organization/contact relationship
orgs_contacts = Table("_orgs_contacts", Base.metadata, Column("org_id", INTEGER, ForeignKey("_organizations.id")), Column("contact_id", INTEGER, ForeignKey("_contacts.id")))
orgs_contacts = Table(
"_orgs_contacts",
Base.metadata,
Column("org_id", INTEGER, ForeignKey("_organizations.id")),
Column("contact_id", INTEGER, ForeignKey("_contacts.id")),
# __table_args__ = {'extend_existing': True}
extend_existing = True
)
class Organization(Base):
"""
Base of organization
"""
__tablename__ = "_organizations"
__table_args__ = {'extend_existing': True}
id = Column(INTEGER, primary_key=True) #: primary key
name = Column(String(64)) #: organization name
@@ -76,6 +85,7 @@ class Contact(Base):
Base of Contact
"""
__tablename__ = "_contacts"
__table_args__ = {'extend_existing': True}
id = Column(INTEGER, primary_key=True) #: primary key
name = Column(String(64)) #: contact name
@@ -126,4 +136,5 @@ class Contact(Base):
limit = 1
case _:
pass
return query_return(query=query, limit=limit)
return query_return(query=query, limit=limit)

View File

@@ -17,7 +17,8 @@ import uuid
import re
import pandas as pd
from openpyxl import Workbook
from tools import check_not_nan, row_map, Base, query_return, setup_lookup
from . import Base
from tools import check_not_nan, row_map, query_return, setup_lookup
from datetime import datetime, date
from typing import List
from dateutil.parser import parse
@@ -29,13 +30,21 @@ from sqlite3 import OperationalError as SQLOperationalError, IntegrityError as S
logger = logging.getLogger(f"submissions.{__name__}")
# table containing reagents/submission relationships
reagents_submissions = Table("_reagents_submissions", Base.metadata, Column("reagent_id", INTEGER, ForeignKey("_reagents.id")), Column("submission_id", INTEGER, ForeignKey("_submissions.id")))
reagents_submissions = Table(
"_reagents_submissions",
Base.metadata,
Column("reagent_id", INTEGER, ForeignKey("_reagents.id")),
Column("submission_id", INTEGER, ForeignKey("_submissions.id")),
extend_existing = True
)
class BasicSubmission(Base):
"""
Concrete of basic submission which polymorphs into BacterialCulture and Wastewater
"""
__tablename__ = "_submissions"
__table_args__ = {'extend_existing': True}
id = Column(INTEGER, primary_key=True) #: primary key
rsl_plate_num = Column(String(32), unique=True, nullable=False) #: RSL name (e.g. RSL-22-0012)
@@ -705,7 +714,6 @@ class Wastewater(BasicSubmission):
"""
derivative submission type from BasicSubmission
"""
# pcr_info = Column(JSON)
ext_technician = Column(String(64))
pcr_technician = Column(String(64))
__mapper_args__ = {"polymorphic_identity": "Wastewater", "polymorphic_load": "inline"}
@@ -948,6 +956,7 @@ class BasicSample(Base):
"""
__tablename__ = "_samples"
__table_args__ = {'extend_existing': True}
id = Column(INTEGER, primary_key=True) #: primary key
submitter_id = Column(String(64), nullable=False, unique=True) #: identification from submitter
@@ -1226,6 +1235,8 @@ class SubmissionSampleAssociation(Base):
DOC: https://docs.sqlalchemy.org/en/14/orm/extensions/associationproxy.html
"""
__tablename__ = "_submission_sample"
__table_args__ = {'extend_existing': True}
sample_id = Column(INTEGER, ForeignKey("_samples.id"), nullable=False)
submission_id = Column(INTEGER, ForeignKey("_submissions.id"), primary_key=True)
row = Column(INTEGER, primary_key=True) #: row on the 96 well plate

View File

@@ -1,7 +1,7 @@
import logging, re
from pathlib import Path
from openpyxl import load_workbook
from backend.db import BasicSubmission, SubmissionType
from backend.db.models import BasicSubmission, SubmissionType
logger = logging.getLogger(f"submissions.{__name__}")