class IruPerson(db.Entity): id = PrimaryKey(int, auto=True) name = Required(str) age = Optional(int) gender = Optional(int) school = Optional(str) enrolling_date = Optional(str) schooling_length = Optional(int) face_encodings = Required(Json)
class Port(db.Entity): num = Required(int) created_at = Required(datetime, default=datetime.utcnow()) updated_at = Required(datetime, default=datetime.utcnow()) host = Required(Host) tags = Optional(str) banner = Optional(str) comment = Optional(str) data = Optional(Json) paths = Set('URLPath')
class Meal(db.Entity): id = PrimaryKey(int, auto=True) buy_date = Required(date) expiration_date = Required(date) freezing_date = Required(date) description = Required(str) units = Required(int) weight = Required(float) unity = Required('Unity') category = Required('Category') subcategory = Optional('SubCategory') drawer = Optional(int) user = Required('User')
class Music(db.Entity): _table_ = "music" id = PrimaryKey(int, auto=True) position = Required(int, auto=0) name = Required(str) artistId = Optional(int, default=0) otherArtistIds = Optional(str) duration = Optional(str) lyrics = Optional(str) extra = Required(str, default="{}", max_len=4096) createTime = Required(datetime, default=datetime.today) lastModifiedTime = Required(datetime, default=datetime.today) lastOperator = Required(str, default="system")
class Album(db.Entity): _table_ = "album" id = PrimaryKey(int, auto=True) image = Optional(str) artistId = Optional(int, default=0) name = Required(str) type = Required(int, default=AlbumType.Unsorted) releaseDate = Required(int, default=1900) label = Optional(str, default="") format = Optional(str, default="CD") duration = Optional(str) extra = Required(str, default="{}", max_len=4096) createTime = Required(datetime, default=datetime.today) lastModifiedTime = Required(datetime, default=datetime.today) lastOperator = Required(str, default="system")
class UserSetting(db.Entity): id = PrimaryKey(int) username = Optional(str) distance = Required(int, default=3000) created_at = Required(datetime, default=datetime.utcnow) updated_at = Required(datetime, default=datetime.utcnow) points_count = Required(int, default=0)
class User(db.Entity, UserMixin): login = Required(str, unique=True) password = Required(str) first_name = Required(str) last_name = Optional(str) created_at = Required(datetime, default=datetime.utcnow) last_login = Optional(datetime, default=datetime.utcnow) friends = Set('User', reverse='friends') sent = Set('Message', reverse='src') rcvd = Set('Message', reverse='dst') def check_password(self, password): return self.password == password def __str__(self): return ('%s %s' % (self.first_name, self.last_name)).rstrip()
class AlbumDownloadInfo(db.Entity): """ Artist table """ _table_ = "album_download_info" id = PrimaryKey(int, auto=True) albumId = Required(int) name = Required(str, max_len=512) src = Required(int) srcAlbumId = Optional(str) srcAlbumUrl = Optional(str) status = Required(int, default=DownloadStatus.NOT) extra = Required(str, default="{}", max_len=4096) createTime = Required(datetime, default=datetime.today) lastModifiedTime = Required(datetime, default=datetime.today) lastOperator = Required(str, default="system")
class DatabaseOrganization(database.Entity): # type: ignore """Organization ORM model""" id = PrimaryKey(UUID, default=uuid4) name = Required(str) users = Set("DatabaseUser") date_created = Required(datetime, default=datetime.utcnow) modified_at = Optional(datetime)
class DatabaseUser(database.Entity): # type: ignore """User ORM model""" id = PrimaryKey(UUID, default=uuid4) organization = Required("DatabaseOrganization") username = Required(str) password = Required(str) date_created = Required(datetime, default=datetime.utcnow) modified_at = Optional(datetime)
class Host(db.Entity): ip = Required(str, unique=True) created_at = Required(datetime, default=datetime.utcnow()) updated_at = Required(datetime, default=datetime.utcnow()) ports = Set('Port') comment = Optional(str) paths = Set('URLPath') def before_update(self): self.updated_at = datetime.utcnow()
class ArtistMemberRelation(db.Entity): _table_ = "artist_relation" id = PrimaryKey(int, auto=True) artistId = Required(int) bandName = Required(str) bandId = Required(int) type = Required(str, default=ArtistBandRelationType.ACTIVE) work = Optional(str) extra = Required(str, default="{}", max_len=4096) createTime = Required(datetime, default=datetime.today) lastModifiedTime = Required(datetime, default=datetime.today) lastOperator = Required(str, default="system")
class RutrackerForumPo(db.Entity): _table_ = "rutracker_forum_info" id = PrimaryKey(int, auto=True) forumId=Required(int, unique=True) name=Required(str, max_len=512) parentId=Required(int, default=0) parentForumId=Required(int) parentUrl=Optional(str, max_len=1024) url=Required(str, max_len=1024) totalPage=Required(int, default=0) extra=Required(str, default="{}", max_len=4096) createTime=Required(datetime, default=datetime.today) lastModifiedTime=Required(datetime, default=datetime.today) lastOperator=Required(str, default="system")
class Artist(db.Entity): """ Artist table """ _table_ = "artist" id = PrimaryKey(int, auto=True) name = Required(str, max_len=512) country = Optional(str) location = Optional(str) image = Optional(str) age = Required(int, default=defaultAge) gender = Required(int, default=GenderEnum.MALE) isBand = Required(int, default=BandEnum.UNKOWN) status = Required(int, default=StatusEnum.ACTIVE) genre = Optional(str) lyricalThemes = Optional(str) currentLabel = Required(str, default="UNKOWN") FormedIn = Required(int, default=0) yearsActive = Optional(str) extra = Required(str, default="{}", max_len=4096) createTime = Required(datetime, default=datetime.today) lastModifiedTime = Required(datetime, default=datetime.today) lastOperator = Required(str, default="system") orm.composite_key(name, country)
class RutrackerForumItemPo(db.Entity): _table_ = "rutracker_forum_item_info" id = PrimaryKey(int, auto=True) topicId=Required(str) topicUrl=Required(str, max_len=1024) forumId=Required(int, default=0) rutrackerForumId=Required(int) topicIcon=Optional(str, max_len=1024) newstLink=Optional(str, max_len=1024) approvedLabel=Optional(str, max_len=128) torTopicTitle=Required(str, max_len=2048) topicAuthor=Required(str, max_len=128) seeders=Optional(int, default=0) leechers=Optional(int, default=0) magnet=Optional(str, max_len=2048, default="") torrentUrl=Optional(str, max_len=1024, default="") fileSize=Optional(str, max_len=32) nReplies=Optional(int, default=0) nDownloads=Optional(int, default=0) lastPostTime=Optional(str) lastPostUser=Optional(str) lastPostUrl=Optional(str)
class PositionMixin: """Mixin qui apporte la possibilté d'ordonner la collection ################################################################ Attention: toujours mettre entity.delete() en fin de dbsession_autodisconnect ################################################################ Dans la nouvelle classe : - spécifier `referent_attribute_name` comme class attribute. Correspond à l'autre côté de la collection. - créer `_position = Required(int) - modifier les fonctions suivantes: ``` def __init__(self, position=None, ref=None, **kwargs): with self.init_position(position, ref) as _position: super().__init__(ref=ref, _position=_position, **kwargs) def before_delete(self): self.before_delete_position() def after_delete(self): self.after_delete_position() def to_dict(**kwargs): dico = super().to_dict(*args, **kwargs) dico["position"] = dico.pop("_position") return dico ``` Le test : def test_delete_mixin_position(self, reset_db): f_ref() Activite(ref=ref) Activite(ref=ref) with dbsession_autodisconnect: assert Activite[1].position == 0 assert Activite[2].position == 1 Activite[1].delete() with dbsession_autodisconnect: assert Activite[2].position == 0 """ referent_attribute_name: str base_class_position: Optional(Entity) = None @property def position(self): return self._position @position.setter def position(self, new): self._position = self._recalcule_position(self._position, new) @classmethod def get_by_position(cls, ref_id): base_class = cls.base_class_position or cls if isinstance(ref_id, str): ref_id = UUID(ref_id) return select(p for p in base_class if getattr(p, base_class.referent_attribute_name).id == ref_id).order_by(base_class._position) def get_referent(self): return getattr(self, self.referent_attribute_name) def _recalcule_position(self, old, new, query=None): base_class = self.base_class_position or self.__class__ if old == new: return new query = (query if query is not None else base_class.get_by_position( self.get_referent().id)) if new >= query.count(): return query.count() elif old < new: for sec in query: if old < sec.position <= new and sec != self: sec._position -= 1 else: # elif old > new: for sec in query: if new <= sec.position < old: sec._position += 1 return new @contextmanager def init_position(self, pos, ref): base_class = self.base_class_position or self.__class__ if isinstance(ref, (Entity, EntityProxy)): ref = ref.id elif isinstance(ref, str): ref = UUID(ref) nb = self.get_by_position(ref).count() if pos is not None: if pos >= nb: yield nb else: query = select( p for p in base_class if getattr(p, self.referent_attribute_name).id == ref and p.position >= pos) for s in query: s._position += 1 yield pos else: query = select( s for s in base_class if getattr(s, self.referent_attribute_name).id == ref) new_pos = query.count() yield new_pos flush() def before_delete_position(self): ref = self.get_referent() self._positionbackup = ( ref.__class__, ref.id, ) def after_delete_position(self): base_class = self.base_class_position or self.__class__ n = 0 try: referent = self._positionbackup[0][self._positionbackup[1]] except ObjectNotFound: return # referent deleted, classement n'a plus d'intéret children = select( p for p in base_class if getattr(p, self.referent_attribute_name) == referent).order_by( base_class._position) for s in children: s._position = n n += 1
class CustomCommandModel(database.Entity): _table_ = "custom_commands" command = PrimaryKey(str) emit = Required(str) counter = Optional(int)
class URLPath(db.Entity): host = Required(Host) port = Required(Port) path = Required(str) cred = Optional(Cred)
class Cred(db.Entity): user = Required(str) password = Optional(str) paths = Set('URLPath')
class Message(db.Entity): src = Required(User, reverse='sent') dst = Optional(User, reverse='rcvd') text = Required(str) created_at = Required(datetime, default=datetime.utcnow) updated_at = Optional(datetime)