bdrc-db-models 2.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- BdrcDbModels/__init__.py +0 -0
- BdrcDbModels/base.py +25 -0
- BdrcDbModels/model_utils.py +81 -0
- BdrcDbModels/models.py +248 -0
- BdrcDbModels/project_manager.py +99 -0
- bdrc_db_models-2.0.2.dist-info/METADATA +282 -0
- bdrc_db_models-2.0.2.dist-info/RECORD +9 -0
- bdrc_db_models-2.0.2.dist-info/WHEEL +5 -0
- bdrc_db_models-2.0.2.dist-info/top_level.txt +1 -0
BdrcDbModels/__init__.py
ADDED
|
File without changes
|
BdrcDbModels/base.py
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import sqlalchemy
|
|
2
|
+
from sqlalchemy.orm import declarative_base
|
|
3
|
+
from sqlalchemy import Column, Integer, text
|
|
4
|
+
from sqlalchemy.dialects.mysql import TIMESTAMP
|
|
5
|
+
|
|
6
|
+
Base = declarative_base()
|
|
7
|
+
|
|
8
|
+
class IdMixin:
|
|
9
|
+
"""
|
|
10
|
+
Provides generic id in primary key
|
|
11
|
+
"""
|
|
12
|
+
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
13
|
+
|
|
14
|
+
class TimestampMixin:
|
|
15
|
+
"""
|
|
16
|
+
Injects created and update times
|
|
17
|
+
"""
|
|
18
|
+
create_time = Column(TIMESTAMP, nullable=False, server_default=text('CURRENT_TIMESTAMP'))
|
|
19
|
+
update_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'))
|
|
20
|
+
|
|
21
|
+
class IdTimestampMixin(IdMixin, TimestampMixin):
|
|
22
|
+
"""
|
|
23
|
+
Provides generic id and create+update time columns
|
|
24
|
+
"""
|
|
25
|
+
pass
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Some utilities. These used to be class members of the DrsDbContextBase,
|
|
3
|
+
but the ORM classes were refactored into this library, so they could not be
|
|
4
|
+
in the BdrcDbLib package (circular reference).
|
|
5
|
+
|
|
6
|
+
Clients who use this will have to use them in the context of a DrsDbContext session.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import logging
|
|
10
|
+
from sqlalchemy import select
|
|
11
|
+
from BdrcDbModels.models import Works, Volumes, GbDownload
|
|
12
|
+
from BdrcDbLib.SqlAlchemy_get_or_create import get_or_create
|
|
13
|
+
|
|
14
|
+
def get_some_works(session) -> list:
|
|
15
|
+
"""
|
|
16
|
+
Test shell. See https://auth0.com/blog/sqlalchemy-orm-tutorial-for-python-developers/
|
|
17
|
+
for starters
|
|
18
|
+
:return:
|
|
19
|
+
"""
|
|
20
|
+
return session.query(Works).filter(Works.WorkName == 'W1FPL2251').all()
|
|
21
|
+
|
|
22
|
+
def get_work_by_name(session, work_name: str) -> Works:
|
|
23
|
+
"""
|
|
24
|
+
Get work by Name
|
|
25
|
+
:param work_name: work to fetch
|
|
26
|
+
:return: MySQL ORM object
|
|
27
|
+
"""
|
|
28
|
+
return session.query(Works).filter(Works.WorkName == work_name).first()
|
|
29
|
+
|
|
30
|
+
def get_or_create_work(session, work_name: str) -> Works:
|
|
31
|
+
"""
|
|
32
|
+
Get or create an object managed in this session
|
|
33
|
+
:param work_name: create or get by work name only
|
|
34
|
+
as you need
|
|
35
|
+
:return: object which matches the input filter, or a new object with the
|
|
36
|
+
**kwargs attributes
|
|
37
|
+
"""
|
|
38
|
+
defaults = {"HOLLIS": '0'}
|
|
39
|
+
o, newly_made = get_or_create(session, Works, defaults, WorkName=work_name)
|
|
40
|
+
if newly_made:
|
|
41
|
+
logging.debug(f"Newly made {o}")
|
|
42
|
+
return o
|
|
43
|
+
|
|
44
|
+
def get_or_create_volume(session, work_name: str, volume_name: str):
|
|
45
|
+
vol_work: Works = get_or_create_work(session, work_name)
|
|
46
|
+
o, newly_made = get_or_create(session, Volumes, label=volume_name, work=vol_work)
|
|
47
|
+
if newly_made:
|
|
48
|
+
logging.debug(f"Newly made {o}")
|
|
49
|
+
return o
|
|
50
|
+
|
|
51
|
+
def get_downloads(session):
|
|
52
|
+
"""
|
|
53
|
+
Gets all the downloads
|
|
54
|
+
"""
|
|
55
|
+
statement = select(GbDownload).order_by(GbDownload.download_time)
|
|
56
|
+
return session.execute(statement).fetchall()
|
|
57
|
+
|
|
58
|
+
def remove_volumes(session, labels: list[str]):
|
|
59
|
+
"""
|
|
60
|
+
Removes a list of volumes identified by their label
|
|
61
|
+
!! Don't use in productionDon't generally use this!
|
|
62
|
+
:param labels: list of volumes to remove
|
|
63
|
+
:return:
|
|
64
|
+
"""
|
|
65
|
+
vols2 = session.query(Volumes).filter(Volumes.label.in_(labels)).all()
|
|
66
|
+
for vv in vols2:
|
|
67
|
+
session.delete(vv)
|
|
68
|
+
session.commit()
|
|
69
|
+
|
|
70
|
+
def remove_works(session, work_names: list[str]):
|
|
71
|
+
"""
|
|
72
|
+
Removes a list of works identified by their WorkName.
|
|
73
|
+
!! Don't use in production
|
|
74
|
+
:param work_names:
|
|
75
|
+
:return:
|
|
76
|
+
"""
|
|
77
|
+
works = session.query(Works).filter(Works.WorkName.in_(work_names)).all()
|
|
78
|
+
for w in works:
|
|
79
|
+
session.delete(w)
|
|
80
|
+
session.commit()
|
|
81
|
+
|
BdrcDbModels/models.py
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Sources:
|
|
3
|
+
toth to https://stackoverflow.com/questions/33743379/sqlalchemy-timestamp-on-update-extra
|
|
4
|
+
create_time = Column(TIMESTAMP, nullable=False, server_default=sqlalchemy.func.now())
|
|
5
|
+
update_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'))
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import sqlalchemy
|
|
10
|
+
from sqlalchemy.orm import declarative_base, relationship
|
|
11
|
+
from sqlalchemy import Column, DateTime, text
|
|
12
|
+
from sqlalchemy import ForeignKey, String, Integer
|
|
13
|
+
from sqlalchemy.dialects.mysql import (
|
|
14
|
+
BIGINT,
|
|
15
|
+
# BINARY,
|
|
16
|
+
# BIT,
|
|
17
|
+
# BLOB,
|
|
18
|
+
# BOOLEAN,
|
|
19
|
+
# CHAR,
|
|
20
|
+
# DATE,
|
|
21
|
+
# DATETIME,
|
|
22
|
+
# DECIMAL,
|
|
23
|
+
# DECIMAL,
|
|
24
|
+
# DOUBLE,
|
|
25
|
+
# ENUM,
|
|
26
|
+
# FLOAT,
|
|
27
|
+
# INTEGER,
|
|
28
|
+
# LONGBLOB,
|
|
29
|
+
LONGTEXT,
|
|
30
|
+
# MEDIUMBLOB,
|
|
31
|
+
# MEDIUMINT,
|
|
32
|
+
# MEDIUMTEXT,
|
|
33
|
+
# NCHAR,
|
|
34
|
+
# NUMERIC,
|
|
35
|
+
# NVARCHAR,
|
|
36
|
+
# REAL,
|
|
37
|
+
# SET,
|
|
38
|
+
# SMALLINT,
|
|
39
|
+
# TEXT,
|
|
40
|
+
# TIME,
|
|
41
|
+
TIMESTAMP,
|
|
42
|
+
# TINYBLOB,
|
|
43
|
+
# TINYINT,
|
|
44
|
+
# TINYTEXT,
|
|
45
|
+
# VARBINARY,
|
|
46
|
+
# VARCHAR,
|
|
47
|
+
# YEAR,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
Base = declarative_base()
|
|
51
|
+
|
|
52
|
+
class IdMixin:
|
|
53
|
+
"""
|
|
54
|
+
Provides generic id in primary key
|
|
55
|
+
"""
|
|
56
|
+
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
57
|
+
|
|
58
|
+
class TimestampMixin:
|
|
59
|
+
"""
|
|
60
|
+
Injects created and update times
|
|
61
|
+
Tip o the hat to https://docs.sqlalchemy.org/en/13/orm/extensions/declarative/mixins.html
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
create_time = Column(TIMESTAMP, nullable=False, server_default=text('CURRENT_TIMESTAMP'))
|
|
65
|
+
update_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'))
|
|
66
|
+
|
|
67
|
+
class IdTimestampMixin(IdMixin, TimestampMixin):
|
|
68
|
+
"""
|
|
69
|
+
Provides generic id and create+update time columns
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
class Works(Base):
|
|
73
|
+
__tablename__ = "Works"
|
|
74
|
+
workId = Column(Integer, primary_key=True, autoincrement=True)
|
|
75
|
+
WorkName = Column(String(45))
|
|
76
|
+
WorkSize = Column(BIGINT)
|
|
77
|
+
HOLLIS = Column(String(45))
|
|
78
|
+
WorkFileCount = Column(BIGINT)
|
|
79
|
+
WorkImageFileCount = Column(BIGINT)
|
|
80
|
+
WorkImageTotalFileSize = Column(BIGINT)
|
|
81
|
+
WorkNonImageFileCount = Column(BIGINT)
|
|
82
|
+
WorkNonImageTotalFileSize = Column(BIGINT)
|
|
83
|
+
|
|
84
|
+
volumes = relationship("Volumes", back_populates='work')
|
|
85
|
+
# gb_metadata = relationship("GBMetadata", back_populates='work')
|
|
86
|
+
|
|
87
|
+
create_time = Column(TIMESTAMP, nullable=False, server_default=text('CURRENT_TIMESTAMP'))
|
|
88
|
+
update_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'))
|
|
89
|
+
|
|
90
|
+
def __repr__(self) -> str:
|
|
91
|
+
return f"id: {self.workId}:{self.WorkName}"
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class Volumes(Base):
|
|
95
|
+
__tablename__ = 'Volumes'
|
|
96
|
+
volumeId = Column(Integer, primary_key=True, autoincrement=True)
|
|
97
|
+
label = Column(String(45))
|
|
98
|
+
workId = Column(Integer, ForeignKey('Works.workId'))
|
|
99
|
+
|
|
100
|
+
work = relationship("Works", back_populates='volumes')
|
|
101
|
+
gb_downloads = relationship("GbDownload", back_populates='volume')
|
|
102
|
+
gb_content = relationship("GbContent", back_populates='volume')
|
|
103
|
+
gb_state = relationship('GbState', back_populates='volume')
|
|
104
|
+
gb_dist = relationship('GbDistribution', back_populates='volume')
|
|
105
|
+
gb_unpack = relationship('GbUnpack', back_populates='volume')
|
|
106
|
+
|
|
107
|
+
create_time = Column(TIMESTAMP, nullable=False, server_default=text('CURRENT_TIMESTAMP'))
|
|
108
|
+
update_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'))
|
|
109
|
+
|
|
110
|
+
def __repr__(self):
|
|
111
|
+
return f"<volume(ig):{self.label} id: {self.volumeId}>"
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class GbMetadata(Base):
|
|
115
|
+
"""
|
|
116
|
+
xxx = GbMetaDataTrack(work_id = workId,upload_time = some_time)
|
|
117
|
+
Record the upload of a work's metadata to GB: columns
|
|
118
|
+
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
|
119
|
+
`update_time` timestamp NULL DEFAULT NULL,
|
|
120
|
+
`id` int(11) NOT NULL AUTO_INCREMENT,
|
|
121
|
+
`work_id` int(11) DEFAULT NULL,
|
|
122
|
+
`upload_time` datetime NOT NULL,
|
|
123
|
+
`upload_result` int(11) DEFAULT NULL,
|
|
124
|
+
"""
|
|
125
|
+
__tablename__ = 'GB_Metadata_Track'
|
|
126
|
+
id: Column = Column(Integer, primary_key=True, autoincrement=True)
|
|
127
|
+
work_id = Column(Integer, ForeignKey('Works.workId'))
|
|
128
|
+
upload_time = Column(TIMESTAMP)
|
|
129
|
+
upload_result = Column(Integer)
|
|
130
|
+
|
|
131
|
+
# work = relationship('Works', back_populates='gb_metadata')
|
|
132
|
+
|
|
133
|
+
create_time = Column(TIMESTAMP, nullable=False, server_default=text('CURRENT_TIMESTAMP'))
|
|
134
|
+
update_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'))
|
|
135
|
+
|
|
136
|
+
def __repr__(self):
|
|
137
|
+
return f"<id: {self.id} upload time:{self.upload_time} work: {self.work_id}>"
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class GbContent(IdTimestampMixin, Base):
|
|
141
|
+
"""
|
|
142
|
+
Records the steps in an **image group's** process. Captures the steps that **this service**
|
|
143
|
+
has performed
|
|
144
|
+
"""
|
|
145
|
+
__tablename__ = 'GB_Content_Track'
|
|
146
|
+
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
147
|
+
volume_id = Column(Integer, ForeignKey('Volumes.volumeId'))
|
|
148
|
+
job_step = Column(String(45))
|
|
149
|
+
step_time = Column(DateTime)
|
|
150
|
+
step_rc = Column(Integer)
|
|
151
|
+
gb_log = Column(LONGTEXT)
|
|
152
|
+
|
|
153
|
+
volume = relationship('Volumes', back_populates='gb_content')
|
|
154
|
+
|
|
155
|
+
create_time = Column(TIMESTAMP, nullable=False, server_default=sqlalchemy.func.now())
|
|
156
|
+
update_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'))
|
|
157
|
+
|
|
158
|
+
def __repr__(self):
|
|
159
|
+
return f"<id: {self.id} step: {self.job_step} step time {self.step_time} volume:{self.volume}"
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
class GbState(Base):
|
|
163
|
+
"""
|
|
164
|
+
Records raw google book data as we poll for it. Captures the state of Google's processing
|
|
165
|
+
volume_id int FK Volumes.volumeId
|
|
166
|
+
job_state varchar(45) -- name of the page reporting this activity
|
|
167
|
+
state_date datetime -- observation datetime
|
|
168
|
+
gb_log longtext -- other columns in the row, as json dict. The programmer has to manually
|
|
169
|
+
determine the columns from the visual page - they do not come down in the
|
|
170
|
+
text version
|
|
171
|
+
"""
|
|
172
|
+
__tablename__ = 'GB_Content_State'
|
|
173
|
+
volume_id = Column(Integer, ForeignKey('Volumes.volumeId'), primary_key=True)
|
|
174
|
+
job_state = Column(String(45), primary_key=True)
|
|
175
|
+
gb_log = Column(LONGTEXT)
|
|
176
|
+
state_date = Column(TIMESTAMP, primary_key=True)
|
|
177
|
+
|
|
178
|
+
volume = relationship('Volumes', back_populates='gb_state')
|
|
179
|
+
|
|
180
|
+
create_time = Column(TIMESTAMP, nullable=False, server_default=text('CURRENT_TIMESTAMP'))
|
|
181
|
+
update_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'))
|
|
182
|
+
|
|
183
|
+
def __repr__(self):
|
|
184
|
+
return f"<volume: {self.volume} state:{self.state}>"
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
class GbDownload(Base):
|
|
188
|
+
__tablename__ = "GB_Downloads"
|
|
189
|
+
id: Column = Column(Integer, primary_key=True, autoincrement=True)
|
|
190
|
+
volume_id = Column(Integer, ForeignKey('Volumes.volumeId'))
|
|
191
|
+
download_object_name = Column(String(255))
|
|
192
|
+
download_path = Column(String(255))
|
|
193
|
+
download_time = Column(TIMESTAMP)
|
|
194
|
+
create_time = Column(TIMESTAMP, nullable=False, server_default=text('CURRENT_TIMESTAMP'))
|
|
195
|
+
update_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'))
|
|
196
|
+
volume = relationship('Volumes', back_populates='gb_downloads')
|
|
197
|
+
|
|
198
|
+
def __repr__(self):
|
|
199
|
+
return f"<volume: {self.volume.label} path: {self.download_path} time: {self.download_time}>"
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
class GbReadyTrack(IdTimestampMixin, Base):
|
|
203
|
+
"""
|
|
204
|
+
Queue of items ready to be acted on
|
|
205
|
+
"""
|
|
206
|
+
__tablename__ = 'GB_Ready_Track'
|
|
207
|
+
target_id = Column(Integer, comment='Id in specific tabel, varies with activity')
|
|
208
|
+
activity = Column(String(50), comment="Supported activities: download unpack")
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
class GbUnpack(IdTimestampMixin, Base):
|
|
212
|
+
__tablename__ = "GB_Unpack"
|
|
213
|
+
volume_id = Column(Integer, ForeignKey('Volumes.volumeId'))
|
|
214
|
+
unpack_object_name = Column(String(255))
|
|
215
|
+
unpacked_path = Column(String(255))
|
|
216
|
+
unpack_time = Column(TIMESTAMP)
|
|
217
|
+
volume = relationship('Volumes', back_populates='gb_unpack')
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
class GbDistribution(IdTimestampMixin, Base):
|
|
221
|
+
"""
|
|
222
|
+
Records the steps in an **image group's** process. Captures the steps that **this service**
|
|
223
|
+
has performed
|
|
224
|
+
"""
|
|
225
|
+
__tablename__ = 'GB_Distribution'
|
|
226
|
+
|
|
227
|
+
volume_id = Column(Integer, ForeignKey('Volumes.volumeId'))
|
|
228
|
+
dist_time = Column(TIMESTAMP)
|
|
229
|
+
src = Column(String(255))
|
|
230
|
+
dest = Column(String(255))
|
|
231
|
+
|
|
232
|
+
volume = relationship('Volumes', back_populates='gb_dist')
|
|
233
|
+
|
|
234
|
+
def __repr__(self):
|
|
235
|
+
return f"<id: {self.id} dist_time {self.dist_time} volume:{self.volume}>"
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
class DipActivities(Base):
|
|
239
|
+
"""
|
|
240
|
+
Legal DIP activities
|
|
241
|
+
"""
|
|
242
|
+
__tablename__ = 'dip_activity_types'
|
|
243
|
+
|
|
244
|
+
id = Column('iddip_activity_types', Integer, primary_key=True, autoincrement=True)
|
|
245
|
+
label = Column('dip_activity_types_label', String(45))
|
|
246
|
+
|
|
247
|
+
def __repr__(self):
|
|
248
|
+
return f"<id: {self.id} label: {self.label}>"
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
from sqlalchemy import Column, text, ForeignKey, String, Integer
|
|
2
|
+
from sqlalchemy.dialects.mysql import LONGTEXT, TIMESTAMP
|
|
3
|
+
from sqlalchemy.orm import relationship
|
|
4
|
+
from .base import Base, IdTimestampMixin, TimestampMixin
|
|
5
|
+
|
|
6
|
+
class ProjectTypes(IdTimestampMixin, Base):
|
|
7
|
+
"""Types of projects, e.g. capture, digitization, distribution, analyis, etc."""
|
|
8
|
+
__tablename__ = "pm_project_types"
|
|
9
|
+
project_type_name = Column(String(45), nullable=False)
|
|
10
|
+
project_type_desc = Column(LONGTEXT)
|
|
11
|
+
project = relationship("Projects", back_populates="project_type")
|
|
12
|
+
|
|
13
|
+
def __repr__(self):
|
|
14
|
+
return f"<{self.id}: {self.project_type_name}>"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Projects(IdTimestampMixin, Base):
|
|
18
|
+
"""Specific projects, e.g. Google books, DRS"""
|
|
19
|
+
__tablename__ = "pm_projects"
|
|
20
|
+
name = Column(String(45))
|
|
21
|
+
description = Column(LONGTEXT)
|
|
22
|
+
|
|
23
|
+
project_type_id = Column(Integer, ForeignKey('pm_project_types.id'))
|
|
24
|
+
project_type = relationship("ProjectTypes", back_populates="project")
|
|
25
|
+
|
|
26
|
+
m_type_id = Column(Integer, ForeignKey('pm_member_types.id'))
|
|
27
|
+
m_type = relationship("MemberTypes", back_populates="project")
|
|
28
|
+
|
|
29
|
+
member = relationship("ProjectMembers", back_populates="project")
|
|
30
|
+
|
|
31
|
+
def __repr__(self):
|
|
32
|
+
return f"<{self.id}: {self.name}-{self.project_type}-{self.m_type}>"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class MemberTypes(IdTimestampMixin, Base):
|
|
36
|
+
"""TUsusally, container level (work, volume).)"""
|
|
37
|
+
__tablename__ = "pm_member_types"
|
|
38
|
+
m_type = Column(String(45), nullable=False)
|
|
39
|
+
project = relationship('Projects', back_populates='m_type')
|
|
40
|
+
members = relationship("MemberTypes", back_populates="member_type")
|
|
41
|
+
|
|
42
|
+
def __repr__(self):
|
|
43
|
+
return f"<{self.id}: {self.m_type}>"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class MemberStates(IdTimestampMixin, Base):
|
|
47
|
+
"""States of project members (See States)"""
|
|
48
|
+
__tablename__ = "pm_member_states"
|
|
49
|
+
m_state_name = Column(String(45), nullable=False)
|
|
50
|
+
m_state_desc = Column(LONGTEXT)
|
|
51
|
+
|
|
52
|
+
project_member = relationship('ProjectMembers', back_populates="project_member_state")
|
|
53
|
+
|
|
54
|
+
def __repr__(self):
|
|
55
|
+
return f"<{self.id}: {self.m_state_name}>"
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class ProjectMembers(TimestampMixin, Base):
|
|
59
|
+
"""An instance of a work or volume in a specific project"""
|
|
60
|
+
__tablename__ = "pm_project_members"
|
|
61
|
+
pm_id = Column(Integer, primary_key=True, autoincrement=True)
|
|
62
|
+
pm_type = Column(Integer, ForeignKey('pm_member_types.id'))
|
|
63
|
+
|
|
64
|
+
pm_work_id = Column(Integer, ForeignKey('Works.workId'))
|
|
65
|
+
pm_volume_id = Column(Integer, ForeignKey('Volumes.volumeId'))
|
|
66
|
+
|
|
67
|
+
pm_project = Column(Integer, ForeignKey('pm_projects.id'))
|
|
68
|
+
project = relationship("Projects", back_populates="member")
|
|
69
|
+
|
|
70
|
+
pm_project_state_id = Column(Integer, ForeignKey('pm_member_states.id'))
|
|
71
|
+
|
|
72
|
+
member_type = relationship("MemberTypes", back_populates="members")
|
|
73
|
+
project_member_state = relationship('MemberStates', back_populates="project_member")
|
|
74
|
+
|
|
75
|
+
def __repr__(self):
|
|
76
|
+
return f"<{self.pm_id}: {self.project} {self.member_type}>"
|
|
77
|
+
|
|
78
|
+
class Steps(IdTimestampMixin, Base):
|
|
79
|
+
"""All possible steps."""
|
|
80
|
+
__tablename__ = "pm_steps"
|
|
81
|
+
s_name = Column(String(45), nullable=False)
|
|
82
|
+
s_desc = Column(LONGTEXT)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class ProjectSteps(IdTimestampMixin, Base):
|
|
86
|
+
"A Step instance in a specific project"""
|
|
87
|
+
__tablename__ = "pm_project_steps"
|
|
88
|
+
ps_project = Column(ForeignKey('pm_projects.id'))
|
|
89
|
+
ps_step = Column(ForeignKey('pm_steps.id'))
|
|
90
|
+
project = relationship("Projects", back_populates="member")
|
|
91
|
+
step = relationship("Steps")
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class ProjectMemberSteps(TimestampMixin, Base):
|
|
95
|
+
"""Lookup table to track steps completed for project members"""
|
|
96
|
+
__tablename__ = "pm_project_member_steps"
|
|
97
|
+
project_member_id = Column(ForeignKey('pm_project_members.pm_id'), primary_key=True)
|
|
98
|
+
project_step_id = Column(ForeignKey("pm_project_steps.id"), primary_key=True)
|
|
99
|
+
project_step_time = Column(TIMESTAMP, nullable=False, server_default=text('CURRENT_TIMESTAMP'))
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bdrc-db-models
|
|
3
|
+
Version: 2.0.2
|
|
4
|
+
Summary: More Secure Bdrc Db library
|
|
5
|
+
Author-email: jimk <jimk@tbrc.org>, Buddhist Digital Resource Center <jimk@tbrc.org>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Operating System :: OS Independent
|
|
9
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
10
|
+
Requires-Python: >=3.9
|
|
11
|
+
Description-Content-Type: text/x-rst
|
|
12
|
+
Requires-Dist: bdrc-db-lib2>=2.0.3a
|
|
13
|
+
Requires-Dist: pytest>=8.4.2
|
|
14
|
+
|
|
15
|
+
==============
|
|
16
|
+
Bdrc Db Models
|
|
17
|
+
==============
|
|
18
|
+
|
|
19
|
+
SqlAlchemy classes representing parts of the DRS database.
|
|
20
|
+
|
|
21
|
+
Schema
|
|
22
|
+
|
|
23
|
+
IdMixin
|
|
24
|
+
=======
|
|
25
|
+
|
|
26
|
+
Provides generic id in primary key
|
|
27
|
+
|
|
28
|
+
**Attributes:**
|
|
29
|
+
|
|
30
|
+
- id
|
|
31
|
+
|
|
32
|
+
TimestampMixin
|
|
33
|
+
==============
|
|
34
|
+
|
|
35
|
+
Injects created and update times
|
|
36
|
+
|
|
37
|
+
**Attributes:**
|
|
38
|
+
|
|
39
|
+
- create_time
|
|
40
|
+
- update_time
|
|
41
|
+
|
|
42
|
+
IdTimestampMixin
|
|
43
|
+
================
|
|
44
|
+
|
|
45
|
+
Provides generic id and create+update time columns
|
|
46
|
+
|
|
47
|
+
ProjectTypes
|
|
48
|
+
============
|
|
49
|
+
|
|
50
|
+
Types of projects, e.g. capture, digitization, distribution, analyis, etc.
|
|
51
|
+
|
|
52
|
+
**Attributes:**
|
|
53
|
+
|
|
54
|
+
- project_type_name
|
|
55
|
+
- project_type_desc
|
|
56
|
+
- project
|
|
57
|
+
|
|
58
|
+
Projects
|
|
59
|
+
========
|
|
60
|
+
|
|
61
|
+
Specific projects, e.g. Google books, DRS
|
|
62
|
+
|
|
63
|
+
**Attributes:**
|
|
64
|
+
|
|
65
|
+
- name
|
|
66
|
+
- description
|
|
67
|
+
- project_type_id
|
|
68
|
+
- project_type
|
|
69
|
+
- m_type_id
|
|
70
|
+
- m_type
|
|
71
|
+
- member
|
|
72
|
+
|
|
73
|
+
MemberTypes
|
|
74
|
+
===========
|
|
75
|
+
|
|
76
|
+
Ususally, container level (work, volume).
|
|
77
|
+
|
|
78
|
+
**Attributes:**
|
|
79
|
+
|
|
80
|
+
- m_type
|
|
81
|
+
- project
|
|
82
|
+
- members
|
|
83
|
+
|
|
84
|
+
MemberStates
|
|
85
|
+
============
|
|
86
|
+
|
|
87
|
+
States of project members (See States)
|
|
88
|
+
|
|
89
|
+
**Attributes:**
|
|
90
|
+
|
|
91
|
+
- m_state_name
|
|
92
|
+
- m_state_desc
|
|
93
|
+
- project_member
|
|
94
|
+
|
|
95
|
+
ProjectMembers
|
|
96
|
+
==============
|
|
97
|
+
|
|
98
|
+
An instance of a work or volume in a specific project
|
|
99
|
+
|
|
100
|
+
**Attributes:**
|
|
101
|
+
|
|
102
|
+
- pm_id
|
|
103
|
+
- pm_type
|
|
104
|
+
- pm_work_id
|
|
105
|
+
- pm_volume_id
|
|
106
|
+
- pm_project
|
|
107
|
+
- project
|
|
108
|
+
- pm_project_state_id
|
|
109
|
+
- member_type
|
|
110
|
+
- project_member_state
|
|
111
|
+
|
|
112
|
+
Steps
|
|
113
|
+
=====
|
|
114
|
+
|
|
115
|
+
All possible steps.
|
|
116
|
+
|
|
117
|
+
**Attributes:**
|
|
118
|
+
|
|
119
|
+
- s_name
|
|
120
|
+
- s_desc
|
|
121
|
+
|
|
122
|
+
ProjectSteps
|
|
123
|
+
============
|
|
124
|
+
|
|
125
|
+
A Step instance in a specific project
|
|
126
|
+
|
|
127
|
+
**Attributes:**
|
|
128
|
+
|
|
129
|
+
- ps_project
|
|
130
|
+
- ps_step
|
|
131
|
+
- project
|
|
132
|
+
- step
|
|
133
|
+
|
|
134
|
+
ProjectMemberSteps
|
|
135
|
+
==================
|
|
136
|
+
|
|
137
|
+
Lookup table to track steps completed for project members
|
|
138
|
+
|
|
139
|
+
**Attributes:**
|
|
140
|
+
|
|
141
|
+
- project_member_id
|
|
142
|
+
- project_step_id
|
|
143
|
+
- project_step_time
|
|
144
|
+
|
|
145
|
+
Works
|
|
146
|
+
=====
|
|
147
|
+
|
|
148
|
+
**Attributes:**
|
|
149
|
+
|
|
150
|
+
- workId
|
|
151
|
+
- WorkName
|
|
152
|
+
- WorkSize
|
|
153
|
+
- HOLLIS
|
|
154
|
+
- WorkFileCount
|
|
155
|
+
- WorkImageFileCount
|
|
156
|
+
- WorkImageTotalFileSize
|
|
157
|
+
- WorkNonImageFileCount
|
|
158
|
+
- WorkNonImageTotalFileSize
|
|
159
|
+
- volumes
|
|
160
|
+
- create_time
|
|
161
|
+
- update_time
|
|
162
|
+
|
|
163
|
+
Volumes
|
|
164
|
+
=======
|
|
165
|
+
|
|
166
|
+
**Attributes:**
|
|
167
|
+
|
|
168
|
+
- volumeId
|
|
169
|
+
- label
|
|
170
|
+
- workId
|
|
171
|
+
- work
|
|
172
|
+
- gb_downloads
|
|
173
|
+
- gb_content
|
|
174
|
+
- gb_state
|
|
175
|
+
- gb_dist
|
|
176
|
+
- gb_unpack
|
|
177
|
+
- create_time
|
|
178
|
+
- update_time
|
|
179
|
+
|
|
180
|
+
GbMetadata
|
|
181
|
+
==========
|
|
182
|
+
|
|
183
|
+
Record the upload of a work's metadata to GB
|
|
184
|
+
|
|
185
|
+
**Attributes:**
|
|
186
|
+
|
|
187
|
+
- id
|
|
188
|
+
- work_id
|
|
189
|
+
- upload_time
|
|
190
|
+
- upload_result
|
|
191
|
+
- create_time
|
|
192
|
+
- update_time
|
|
193
|
+
|
|
194
|
+
GbContent
|
|
195
|
+
=========
|
|
196
|
+
|
|
197
|
+
Records the steps in an **image group's** process. Captures the steps that **this service** has performed
|
|
198
|
+
|
|
199
|
+
**Attributes:**
|
|
200
|
+
|
|
201
|
+
- id
|
|
202
|
+
- volume_id
|
|
203
|
+
- job_step
|
|
204
|
+
- step_time
|
|
205
|
+
- step_rc
|
|
206
|
+
- gb_log
|
|
207
|
+
- volume
|
|
208
|
+
- create_time
|
|
209
|
+
- update_time
|
|
210
|
+
|
|
211
|
+
GbState
|
|
212
|
+
=======
|
|
213
|
+
|
|
214
|
+
Records raw google book data as we poll for it. Captures the state of Google's processing
|
|
215
|
+
|
|
216
|
+
**Attributes:**
|
|
217
|
+
|
|
218
|
+
- volume_id
|
|
219
|
+
- job_state
|
|
220
|
+
- gb_log
|
|
221
|
+
- state_date
|
|
222
|
+
- volume
|
|
223
|
+
- create_time
|
|
224
|
+
- update_time
|
|
225
|
+
|
|
226
|
+
GbDownload
|
|
227
|
+
==========
|
|
228
|
+
|
|
229
|
+
**Attributes:**
|
|
230
|
+
|
|
231
|
+
- id
|
|
232
|
+
- volume_id
|
|
233
|
+
- download_object_name
|
|
234
|
+
- download_path
|
|
235
|
+
- download_time
|
|
236
|
+
- create_time
|
|
237
|
+
- update_time
|
|
238
|
+
- volume
|
|
239
|
+
|
|
240
|
+
GbReadyTrack
|
|
241
|
+
============
|
|
242
|
+
|
|
243
|
+
Queue of items ready to be acted on
|
|
244
|
+
|
|
245
|
+
**Attributes:**
|
|
246
|
+
|
|
247
|
+
- target_id
|
|
248
|
+
- activity
|
|
249
|
+
|
|
250
|
+
GbUnpack
|
|
251
|
+
========
|
|
252
|
+
|
|
253
|
+
**Attributes:**
|
|
254
|
+
|
|
255
|
+
- volume_id
|
|
256
|
+
- unpack_object_name
|
|
257
|
+
- unpacked_path
|
|
258
|
+
- unpack_time
|
|
259
|
+
- volume
|
|
260
|
+
|
|
261
|
+
GbDistribution
|
|
262
|
+
==============
|
|
263
|
+
|
|
264
|
+
Records the steps in an **image group's** process. Captures the steps that **this service** has performed
|
|
265
|
+
|
|
266
|
+
**Attributes:**
|
|
267
|
+
|
|
268
|
+
- volume_id
|
|
269
|
+
- dist_time
|
|
270
|
+
- src
|
|
271
|
+
- dest
|
|
272
|
+
- volume
|
|
273
|
+
|
|
274
|
+
DipActivities
|
|
275
|
+
=============
|
|
276
|
+
|
|
277
|
+
Legal DIP activities
|
|
278
|
+
|
|
279
|
+
**Attributes:**
|
|
280
|
+
|
|
281
|
+
- id
|
|
282
|
+
- label
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
BdrcDbModels/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
BdrcDbModels/base.py,sha256=wleH1Z2OjT972Vji8GoZBRX15Siq_SKKp56-28ttcVw,722
|
|
3
|
+
BdrcDbModels/model_utils.py,sha256=QKKu0oFTrfxJ7N4x8gqDijy3JCLPS7e6FXB5kRJ4Mvw,2621
|
|
4
|
+
BdrcDbModels/models.py,sha256=6a4c9ve95Lm8l8SdxWkMgFOmMeaG3tbjUo5QcJ0Xm2g,8720
|
|
5
|
+
BdrcDbModels/project_manager.py,sha256=LxiwSirieIOtqIjPsuw3X2QPWYB0Ua85rz-KrL9jTpQ,3888
|
|
6
|
+
bdrc_db_models-2.0.2.dist-info/METADATA,sha256=XWyR40teVbRjdZpu7NylhS9PPnvrF4OL92hpHFMUkG8,3691
|
|
7
|
+
bdrc_db_models-2.0.2.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
8
|
+
bdrc_db_models-2.0.2.dist-info/top_level.txt,sha256=q9XwX-TnCxFQStst5wsLxB8Hp0L0HQ5VNVaFjmYGVvU,13
|
|
9
|
+
bdrc_db_models-2.0.2.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
BdrcDbModels
|