Coverage for src/nendo/library/model.py: 98%
116 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-11-18 16:37 +0100
« prev ^ index » next coverage.py v7.3.2, created at 2023-11-18 16:37 +0100
1# -*- encoding: utf-8 -*-
2# ruff: noqa: A003
3"""Module containing all SQLAlchemy ORM models for the nendo core schema.
5Used by the SQLAlchemy implementation of the nendo library.
6"""
8from __future__ import annotations
10import json
11import uuid
12from datetime import date, datetime
14import numpy as np
15from sqlalchemy import Column, DateTime, ForeignKey, Integer, MetaData, String
16from sqlalchemy.dialects.postgresql import ENUM, JSON, UUID
17from sqlalchemy.orm import declarative_base, relationship
18from sqlalchemy.sql import func
19from sqlalchemy.sql.sqltypes import Text
20from sqlalchemy.types import TypeDecorator
21from sqlalchemy_json import NestedMutableDict, NestedMutableList, mutable_json_type
23from nendo import schema
25Base = declarative_base(metadata=MetaData())
28def convert(obj):
29 if isinstance(obj, uuid.UUID):
30 return str(obj)
31 if isinstance(obj, (datetime, date)):
32 return obj.isoformat()
33 if isinstance(obj, set):
34 return convert(list(obj))
35 if isinstance(obj, np.float32):
36 return float(obj)
37 if isinstance(obj, NestedMutableList) or isinstance(obj, list):
38 return [convert(x) for x in obj]
39 if isinstance(obj, NestedMutableDict) or isinstance(obj, dict):
40 return {k: convert(v) for k, v in obj.items()}
41 return obj
44class JSONEncodedDict(TypeDecorator):
45 impl = JSON
47 def process_bind_param(self, value, dialect):
48 return json.dumps(convert(value))
50 def process_result_value(self, value, dialect):
51 if value is not None:
52 return json.loads(value)
55class TrackTrackRelationshipDB(Base):
56 __tablename__ = "track_track_relationships"
57 id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
58 source_id = Column(UUID(as_uuid=True), ForeignKey("tracks.id"))
59 target_id = Column(UUID(as_uuid=True), ForeignKey("tracks.id"))
60 created_at = Column(DateTime(timezone=True), server_default=func.now())
61 updated_at = Column(
62 DateTime(timezone=True), server_default=func.now(), onupdate=func.now()
63 )
64 relationship_type = Column(String)
65 meta = Column(mutable_json_type(dbtype=JSONEncodedDict, nested=True))
67 # relationships
68 source = relationship(
69 "NendoTrackDB",
70 foreign_keys=[source_id],
71 back_populates="related_tracks",
72 )
73 target = relationship("NendoTrackDB", foreign_keys=[target_id])
76class TrackCollectionRelationshipDB(Base):
77 __tablename__ = "track_collection_relationships"
78 id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
79 source_id = Column(UUID(as_uuid=True), ForeignKey("tracks.id"))
80 target_id = Column(UUID(as_uuid=True), ForeignKey("collections.id"))
81 created_at = Column(DateTime(timezone=True), server_default=func.now())
82 updated_at = Column(
83 DateTime(timezone=True),
84 server_default=func.now(),
85 onupdate=func.now(),
86 )
87 relationship_type = Column(String)
88 meta = Column(mutable_json_type(dbtype=JSONEncodedDict, nested=True))
89 relationship_position = Column(Integer, nullable=False)
91 # relationships
92 source = relationship("NendoTrackDB", foreign_keys=[source_id])
93 target = relationship("NendoCollectionDB", foreign_keys=[target_id])
96class CollectionCollectionRelationshipDB(Base):
97 __tablename__ = "collection_collection_relationships"
98 id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
99 source_id = Column(UUID(as_uuid=True), ForeignKey("collections.id"))
100 target_id = Column(UUID(as_uuid=True), ForeignKey("collections.id"))
101 created_at = Column(DateTime(timezone=True), server_default=func.now())
102 updated_at = Column(
103 DateTime(timezone=True),
104 server_default=func.now(),
105 onupdate=func.now(),
106 )
107 relationship_type = Column(String)
108 meta = Column(mutable_json_type(dbtype=JSONEncodedDict, nested=True))
110 # relationships
111 source = relationship("NendoCollectionDB", foreign_keys=[source_id])
112 target = relationship("NendoCollectionDB", foreign_keys=[target_id])
115class NendoPluginDataDB(Base):
116 __tablename__ = "plugin_data"
118 id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
119 track_id = Column(UUID(as_uuid=True), ForeignKey("tracks.id"))
120 user_id = Column(UUID(as_uuid=True)) # , ForeignKey("users.id"))
121 plugin_name = Column(String, nullable=False)
122 plugin_version = Column(String, nullable=False)
123 key = Column(String, nullable=False)
124 value = Column(String, nullable=True)
125 created_at = Column(DateTime(timezone=True), server_default=func.now())
126 updated_at = Column(
127 DateTime(timezone=True),
128 server_default=func.now(),
129 onupdate=func.now(),
130 )
132 # relationships
133 # track = relationship("NendoTrackDB", backref="plugin_data")
136class NendoTrackDB(Base):
137 __tablename__ = "tracks"
139 id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
140 user_id = Column(UUID(as_uuid=True))
141 track_type = Column(String, default="track")
142 visibility = Column(ENUM(schema.Visibility), default="private")
143 updated_at = Column(
144 DateTime(timezone=True), default=func.now(), onupdate=func.now()
145 )
146 created_at = Column(DateTime(timezone=True), default=func.now())
147 images = Column(mutable_json_type(dbtype=JSONEncodedDict, nested=True))
148 resource = Column(mutable_json_type(dbtype=JSONEncodedDict, nested=True))
149 meta = Column(mutable_json_type(dbtype=JSONEncodedDict, nested=True))
151 # Relationships
152 related_tracks = relationship(
153 "TrackTrackRelationshipDB",
154 primaryjoin="NendoTrackDB.id==TrackTrackRelationshipDB.source_id",
155 foreign_keys="[TrackTrackRelationshipDB.source_id]",
156 back_populates="source",
157 # cascade="all, delete-orphan",
158 )
159 related_collections = relationship(
160 "TrackCollectionRelationshipDB",
161 primaryjoin="NendoTrackDB.id==TrackCollectionRelationshipDB.source_id",
162 foreign_keys="[TrackCollectionRelationshipDB.source_id]",
163 back_populates="source",
164 # cascade="all, delete-orphan",
165 )
166 plugin_data = relationship(
167 "NendoPluginDataDB",
168 primaryjoin="NendoTrackDB.id==NendoPluginDataDB.track_id",
169 foreign_keys="[NendoPluginDataDB.track_id]",
170 # cascade="all, delete-orphan",
171 )
174class NendoBlobDB(Base):
175 __tablename__ = "blobs"
177 id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
178 user_id = Column(UUID(as_uuid=True))
179 visibility = Column(ENUM(schema.Visibility), default="private")
180 updated_at = Column(
181 DateTime(timezone=True),
182 default=func.now(),
183 onupdate=func.now(),
184 )
185 created_at = Column(DateTime(timezone=True), default=func.now())
186 resource = Column(mutable_json_type(dbtype=JSONEncodedDict, nested=True))
189class NendoCollectionDB(Base):
190 __tablename__ = "collections"
192 id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
193 name = Column(String)
194 user_id = Column(UUID(as_uuid=True))
195 description = Column(Text, default="")
196 collection_type = Column(String, default="generic")
197 visibility = Column(ENUM(schema.Visibility), default="private")
198 updated_at = Column(
199 DateTime(timezone=True),
200 default=func.now(),
201 onupdate=func.now(),
202 )
203 created_at = Column(DateTime(timezone=True), default=func.now())
204 meta = Column(mutable_json_type(dbtype=JSONEncodedDict, nested=True))
206 # relationships
207 related_tracks = relationship(
208 "TrackCollectionRelationshipDB",
209 primaryjoin="NendoCollectionDB.id==TrackCollectionRelationshipDB.target_id",
210 foreign_keys="[TrackCollectionRelationshipDB.target_id]",
211 back_populates="target",
212 # cascade="all, delete-orphan",
213 )
215 related_collections = relationship(
216 "CollectionCollectionRelationshipDB",
217 primaryjoin="NendoCollectionDB.id==CollectionCollectionRelationshipDB.source_id",
218 foreign_keys="[CollectionCollectionRelationshipDB.source_id]",
219 back_populates="source",
220 # cascade="all, delete-orphan",
221 )