Coverage for cc_modules/cc_dataclasses.py: 64%
33 statements
« prev ^ index » next coverage.py v6.5.0, created at 2022-11-08 23:14 +0000
« prev ^ index » next coverage.py v6.5.0, created at 2022-11-08 23:14 +0000
1#!/usr/bin/env python
3"""
4camcops_server/cc_modules/cc_dataclasses.py
6===============================================================================
8 Copyright (C) 2012, University of Cambridge, Department of Psychiatry.
9 Created by Rudolf Cardinal (rnc1001@cam.ac.uk).
11 This file is part of CamCOPS.
13 CamCOPS is free software: you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
18 CamCOPS is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with CamCOPS. If not, see <https://www.gnu.org/licenses/>.
26===============================================================================
28**Dataclasses.**
30"""
32from dataclasses import dataclass
33from typing import Dict, TYPE_CHECKING
35if TYPE_CHECKING:
36 from sqlalchemy.sql.schema import Column
37 from camcops_server.cc_modules.cc_summaryelement import SummaryElement
40# =============================================================================
41# SummarySchemaInfo
42# =============================================================================
45@dataclass(eq=True, frozen=True, order=True) # hashable, sortable
46class SummarySchemaInfo:
47 """
48 Information to be given to the user about the schema for spreadsheet-style
49 downloads, including database and summary columns.
50 """
52 # Summary schema values:
53 SSV_DB = "database"
54 SSV_SUMMARY = "summary"
55 VALID_SOURCES = {SSV_DB, SSV_SUMMARY}
57 table_name: str
58 source: str
59 column_name: str
60 data_type: str
61 comment: str
63 def __post_init__(self) -> None:
64 assert (
65 self.source in self.VALID_SOURCES
66 ), f"Bad source: {self.source!r}"
68 @property
69 def as_dict(self) -> Dict[str, str]:
70 """
71 Used to create spreadsheet rows. Maps spreadsheet headings to values.
72 """
73 return {
74 "table_name": self.table_name,
75 "source": self.source,
76 "column_name": self.column_name,
77 "data_type": self.data_type,
78 "comment": self.comment,
79 }
81 @classmethod
82 def from_column(
83 cls,
84 column: "Column",
85 table_name: str = "",
86 source: str = "",
87 column_name_prefix: str = "",
88 ) -> "SummarySchemaInfo":
89 """
90 Create from an SQLAlchemy column.
91 """
92 if not table_name:
93 if column.table is not None:
94 table_name = column.table.name
95 else:
96 raise ValueError(
97 f"table_name not specified and column not "
98 f"attached to a table: {column!r}"
99 )
100 source = source or cls.SSV_DB
101 return cls(
102 table_name=table_name,
103 source=source,
104 column_name=column_name_prefix + column.name,
105 data_type=str(column.type),
106 comment=column.comment,
107 )
109 @classmethod
110 def from_summary_element(
111 cls,
112 table_name: str,
113 element: "SummaryElement",
114 source: str = "",
115 column_name_prefix: str = "",
116 ) -> "SummarySchemaInfo":
117 """
118 Create from a
119 :class:`camcops_server.cc_modules.cc_summaryelement.SummarySchemaInfo`.
120 """
121 source = source or cls.SSV_SUMMARY
122 return cls(
123 table_name=table_name,
124 source=source,
125 column_name=column_name_prefix + element.name,
126 data_type=str(element.coltype),
127 comment=element.decorated_comment,
128 )