Coverage for dj/models/attribute.py: 100%

31 statements  

« prev     ^ index     » next       coverage.py v7.2.3, created at 2023-04-17 20:05 -0700

1""" 

2Models for attributes. 

3""" 

4import enum 

5from typing import TYPE_CHECKING, List, Optional 

6 

7from sqlalchemy import JSON, String, UniqueConstraint 

8from sqlalchemy.sql.schema import Column as SqlaColumn 

9from sqlmodel import Field, Relationship 

10 

11from dj.models.base import BaseSQLModel 

12from dj.models.node import NodeType 

13 

14if TYPE_CHECKING: 

15 from dj.models import Column 

16 

17 

18RESERVED_ATTRIBUTE_NAMESPACE = "system" 

19 

20 

21class MutableAttributeTypeFields(BaseSQLModel): 

22 """ 

23 Fields on attribute types that users can set. 

24 """ 

25 

26 namespace: str 

27 name: str = Field(sa_column=SqlaColumn("name", String)) 

28 description: str 

29 allowed_node_types: List[NodeType] = Field(sa_column=SqlaColumn(JSON)) 

30 

31 

32class UniquenessScope(str, enum.Enum): 

33 """ 

34 The scope at which this attribute needs to be unique. 

35 """ 

36 

37 NODE = "node" 

38 COLUMN_TYPE = "column_type" 

39 

40 

41class RestrictedAttributeTypeFields(BaseSQLModel): 

42 """ 

43 Fields on attribute types that aren't configurable by users. 

44 """ 

45 

46 uniqueness_scope: List[UniquenessScope] = Field( 

47 default=[], 

48 sa_column=SqlaColumn(JSON), 

49 ) 

50 

51 

52class AttributeTypeBase(MutableAttributeTypeFields, RestrictedAttributeTypeFields): 

53 """Base attribute type.""" 

54 

55 

56class AttributeType(AttributeTypeBase, table=True): # type: ignore # pylint: disable=too-many-ancestors 

57 """ 

58 Available attribute types for column metadata. 

59 """ 

60 

61 __table_args__ = (UniqueConstraint("namespace", "name"),) 

62 

63 id: Optional[int] = Field(default=None, primary_key=True) 

64 

65 def __hash__(self): 

66 return hash(self.id) 

67 

68 

69class ColumnAttribute(BaseSQLModel, table=True): # type: ignore 

70 """ 

71 Column attributes. 

72 """ 

73 

74 __table_args__ = (UniqueConstraint("attribute_type_id", "column_id"),) 

75 

76 id: Optional[int] = Field(default=None, primary_key=True) 

77 attribute_type_id: Optional[int] = Field( 

78 default=None, 

79 foreign_key="attributetype.id", 

80 ) 

81 attribute_type: AttributeType = Relationship() 

82 

83 column_id: Optional[int] = Field(default=None, foreign_key="column.id") 

84 column: "Column" = Relationship(back_populates="attributes")