6
0

Label.py 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. from datetime import datetime
  2. from pycs import db
  3. from pycs.database.base import NamedBaseModel
  4. from pycs.database.util import commit_on_return
  5. def compare_children(start_label: Label, id: int) -> bool:
  6. """ check for cyclic relationships """
  7. labels_to_check = [start_label]
  8. while labels_to_check:
  9. label = labels_to_check.pop(0)
  10. if label.id == id:
  11. return False
  12. labels_to_check.extend(label.children)
  13. return True
  14. def _Label_id():
  15. return Label.id
  16. class Label(NamedBaseModel):
  17. id = db.Column(db.Integer, primary_key=True)
  18. project_id = db.Column(
  19. db.Integer,
  20. db.ForeignKey("project.id", ondelete="CASCADE"),
  21. nullable=False)
  22. parent_id = db.Column(
  23. db.Integer,
  24. db.ForeignKey("label.id", ondelete="SET NULL"))
  25. created = db.Column(db.DateTime, default=datetime.utcnow,
  26. index=True, nullable=False)
  27. reference = db.Column(db.String)
  28. # contraints
  29. __table_args__ = (
  30. db.UniqueConstraint('project_id', 'reference'),
  31. )
  32. # relationships to other models
  33. parent = db.relationship("Label",
  34. backref="children",
  35. remote_side=_Label_id)
  36. results = db.relationship("Result",
  37. backref="label",
  38. passive_deletes=True,
  39. lazy="dynamic",
  40. )
  41. serialize_only = NamedBaseModel.serialize_only + (
  42. "project_id",
  43. "parent_id",
  44. "reference",
  45. "children",
  46. )
  47. @commit_on_return
  48. def set_parent(self, parent_id: int) -> None:
  49. """
  50. set this labels parent
  51. :param parent_id: parent's id
  52. :return:
  53. """
  54. if not compare_children(self, parent_id):
  55. raise ValueError('Cyclic relationship detected!')
  56. self.parent_id = parent_id