Coverage for .tox/coverage/lib/python3.11/site-packages/wuttjamaican/db/model/base.py: 100%

27 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2024-08-30 20:36 -0500

1# -*- coding: utf-8; -*- 

2################################################################################ 

3# 

4# WuttJamaican -- Base package for Wutta Framework 

5# Copyright © 2023-2024 Lance Edgar 

6# 

7# This file is part of Wutta Framework. 

8# 

9# Wutta Framework is free software: you can redistribute it and/or modify it 

10# under the terms of the GNU General Public License as published by the Free 

11# Software Foundation, either version 3 of the License, or (at your option) any 

12# later version. 

13# 

14# Wutta Framework is distributed in the hope that it will be useful, but 

15# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 

16# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 

17# more details. 

18# 

19# You should have received a copy of the GNU General Public License along with 

20# Wutta Framework. If not, see <http://www.gnu.org/licenses/>. 

21# 

22################################################################################ 

23""" 

24Base Models 

25 

26.. class:: Base 

27 

28 This is the base class for all data models. 

29""" 

30 

31import sqlalchemy as sa 

32from sqlalchemy import orm 

33 

34from wuttjamaican.db.util import (naming_convention, ModelBase, 

35 uuid_column, uuid_fk_column) 

36 

37 

38metadata = sa.MetaData(naming_convention=naming_convention) 

39 

40Base = orm.declarative_base(metadata=metadata, cls=ModelBase) 

41 

42 

43class Setting(Base): 

44 """ 

45 Represents a :term:`config setting`. 

46 """ 

47 __tablename__ = 'setting' 

48 

49 name = sa.Column(sa.String(length=255), primary_key=True, nullable=False, doc=""" 

50 Unique name for the setting. 

51 """) 

52 

53 value = sa.Column(sa.Text(), nullable=True, doc=""" 

54 String value for the setting. 

55 """) 

56 

57 def __str__(self): 

58 return self.name or "" 

59 

60 

61class Person(Base): 

62 """ 

63 Represents a person. 

64 

65 The use for this table in the base framework, is to associate with 

66 a :class:`~wuttjamaican.db.model.auth.User` to provide first and 

67 last name etc. (However a user does not have to be associated 

68 with any person.) 

69 

70 But this table could also be used as a basis for a Customer or 

71 Employee relationship etc. 

72 """ 

73 __tablename__ = 'person' 

74 __versioned__ = {} 

75 

76 uuid = uuid_column() 

77 

78 full_name = sa.Column(sa.String(length=100), nullable=False, doc=""" 

79 Full name for the person. Note that this is *required*. 

80 """) 

81 

82 first_name = sa.Column(sa.String(length=50), nullable=True, doc=""" 

83 The person's first name. 

84 """) 

85 

86 middle_name = sa.Column(sa.String(length=50), nullable=True, doc=""" 

87 The person's middle name or initial. 

88 """) 

89 

90 last_name = sa.Column(sa.String(length=50), nullable=True, doc=""" 

91 The person's last name. 

92 """) 

93 

94 users = orm.relationship( 

95 'User', 

96 back_populates='person', 

97 cascade_backrefs=False, 

98 doc=""" 

99 List of :class:`~wuttjamaican.db.model.auth.User` accounts for 

100 the person. Typically there is only one user account per 

101 person, but technically multiple are supported. 

102 """) 

103 

104 def __str__(self): 

105 return self.full_name or "" 

106 

107 @property 

108 def user(self): 

109 """ 

110 Reference to the "first" 

111 :class:`~wuttjamaican.db.model.auth.User` account for the 

112 person, or ``None``. 

113 

114 .. warning:: 

115 

116 Note that the database schema supports multiple users per 

117 person, but this property logic ignores that and will only 

118 ever return "one or none". That might be fine in 99% of 

119 cases, but if multiple accounts exist for a person, the one 

120 returned is indeterminate. 

121 

122 See :attr:`users` to access the full list. 

123 """ 

124 

125 # TODO: i'm not crazy about the ambiguity here re: number of 

126 # user accounts a person may have. in particular it's not 

127 # clear *which* user account would be returned, as there is no 

128 # sequence ordinal defined etc. a better approach might be to 

129 # force callers to assume the possibility of multiple 

130 # user accounts per person? (if so, remove this property) 

131 

132 if self.users: 

133 return self.users[0]