server/tags: simplify relations model

This commit is contained in:
rr- 2016-04-17 12:53:23 +02:00
parent 888e8e1aa7
commit 9ac70dbed4
7 changed files with 52 additions and 59 deletions

View file

@ -8,9 +8,9 @@ def _serialize_tag(tag):
'names': [tag_name.name for tag_name in tag.names],
'category': tag.category,
'suggestions': [
relation.child_tag.names[0].name for relation in tag.suggestions],
relation.names[0].name for relation in tag.suggestions],
'implications': [
relation.child_tag.names[0].name for relation in tag.implications],
relation.names[0].name for relation in tag.implications],
'creationTime': tag.creation_time,
'lastEditTime': tag.last_edit_time,
}

View file

@ -4,56 +4,53 @@ from szurubooru.db.base import Base
class TagSuggestion(Base):
__tablename__ = 'tag_suggestion'
parent_id = Column('parent_id', Integer, ForeignKey('tag.id'), primary_key=True)
child_id = Column('child_id', Integer, ForeignKey('tag.id'), primary_key=True)
def __init__(self, parent_id, child_id):
self.parent_id = parent_id
self.child_id = child_id
class TagImplication(Base):
__tablename__ = 'tag_implication'
parent_id = Column('parent_id', Integer, ForeignKey('tag.id'), primary_key=True)
child_id = Column('child_id', Integer, ForeignKey('tag.id'), primary_key=True)
def __init__(self, parent_id, child_id):
self.parent_id = parent_id
self.child_id = child_id
class Tag(Base):
__tablename__ = 'tag'
tag_id = Column('id', Integer, primary_key=True)
category = Column('category', String(32), nullable=False)
creation_time = Column('creation_time', DateTime, nullable=False)
last_edit_time = Column('last_edit_time', DateTime)
post_count = Column('auto_post_count', Integer, nullable=False, default=0)
names = relationship('TagName', cascade='all, delete-orphan')
suggestions = relationship(
TagSuggestion,
backref='parent_tag',
primaryjoin=tag_id == TagSuggestion.parent_id,
cascade='all, delete-orphan')
suggested_by = relationship(
TagSuggestion,
backref='child_tag',
primaryjoin=tag_id == TagSuggestion.child_id,
cascade='all, delete-orphan')
implications = relationship(
TagImplication,
backref='parent_tag',
primaryjoin=tag_id == TagImplication.parent_id,
cascade='all, delete-orphan')
implied_by = relationship(
TagImplication,
backref='child_tag',
primaryjoin=tag_id == TagImplication.child_id,
cascade='all, delete-orphan')
class TagName(Base):
__tablename__ = 'tag_name'
tag_name_id = Column('tag_name_id', Integer, primary_key=True)
tag_id = Column('tag_id', Integer, ForeignKey('tag.id'))
name = Column('name', String(64), nullable=False, unique=True)
def __init__(self, name):
self.name = name
class Tag(Base):
__tablename__ = 'tag'
tag_id = Column('id', Integer, primary_key=True)
category = Column('category', String(32), nullable=False)
creation_time = Column('creation_time', DateTime, nullable=False)
last_edit_time = Column('last_edit_time', DateTime)
names = relationship('TagName', cascade='all, delete-orphan')
suggestions = relationship(
'Tag',
secondary='tag_suggestion',
primaryjoin=tag_id == TagSuggestion.parent_id,
secondaryjoin=tag_id == TagSuggestion.child_id)
implications = relationship(
'Tag',
secondary='tag_implication',
primaryjoin=tag_id == TagImplication.parent_id,
secondaryjoin=tag_id == TagImplication.child_id)
# TODO: wire this
post_count = Column('auto_post_count', Integer, nullable=False, default=0)

View file

@ -11,7 +11,7 @@ def get_tag(session, name):
.first()
def assert_relations(relations, expected_tag_names):
actual_names = [rel.child_tag.names[0].name for rel in relations]
actual_names = [rel.names[0].name for rel in relations]
assert actual_names == expected_tag_names
@pytest.fixture

View file

@ -11,7 +11,7 @@ def get_tag(session, name):
.first()
def assert_relations(relations, expected_tag_names):
actual_names = [rel.child_tag.names[0].name for rel in relations]
actual_names = [rel.names[0].name for rel in relations]
assert actual_names == expected_tag_names
@pytest.fixture

View file

@ -23,10 +23,10 @@ def test_saving_tag(session, tag_factory):
assert suggested_tag2.tag_id is not None
assert implied_tag1.tag_id is not None
assert implied_tag2.tag_id is not None
tag.suggestions.append(db.TagSuggestion(tag.tag_id, suggested_tag1.tag_id))
tag.suggestions.append(db.TagSuggestion(tag.tag_id, suggested_tag2.tag_id))
tag.implications.append(db.TagImplication(tag.tag_id, implied_tag1.tag_id))
tag.implications.append(db.TagImplication(tag.tag_id, implied_tag2.tag_id))
tag.suggestions.append(suggested_tag1)
tag.suggestions.append(suggested_tag2)
tag.implications.append(implied_tag1)
tag.implications.append(implied_tag2)
session.commit()
tag = session.query(db.Tag) \
@ -38,9 +38,9 @@ def test_saving_tag(session, tag_factory):
assert tag.creation_time == datetime(1997, 1, 1)
assert tag.last_edit_time == datetime(1998, 1, 1)
assert tag.post_count == 1
assert [relation.child_tag.names[0].name for relation in tag.suggestions] \
assert [relation.names[0].name for relation in tag.suggestions] \
== ['suggested1', 'suggested2']
assert [relation.child_tag.names[0].name for relation in tag.implications] \
assert [relation.names[0].name for relation in tag.implications] \
== ['implied1', 'implied2']
def test_cascade_deletions(session, tag_factory):
@ -65,10 +65,10 @@ def test_cascade_deletions(session, tag_factory):
assert suggested_tag2.tag_id is not None
assert implied_tag1.tag_id is not None
assert implied_tag2.tag_id is not None
tag.suggestions.append(db.TagSuggestion(tag.tag_id, suggested_tag1.tag_id))
tag.suggestions.append(db.TagSuggestion(tag.tag_id, suggested_tag2.tag_id))
tag.implications.append(db.TagImplication(tag.tag_id, implied_tag1.tag_id))
tag.implications.append(db.TagImplication(tag.tag_id, implied_tag2.tag_id))
tag.suggestions.append(suggested_tag1)
tag.suggestions.append(suggested_tag2)
tag.implications.append(implied_tag1)
tag.implications.append(implied_tag2)
session.commit()
session.delete(tag)

View file

@ -133,9 +133,9 @@ def test_order_by_suggestion_count(
tag2 = tag_factory(names=['t2'])
session.add_all([sug1, sug3, tag2, sug2, tag1])
session.commit()
tag1.suggestions.append(db.TagSuggestion(tag1.tag_id, sug1.tag_id))
tag1.suggestions.append(db.TagSuggestion(tag1.tag_id, sug2.tag_id))
tag2.suggestions.append(db.TagSuggestion(tag2.tag_id, sug3.tag_id))
tag1.suggestions.append(sug1)
tag1.suggestions.append(sug2)
tag2.suggestions.append(sug3)
verify_unpaged(input, expected_tag_names)
@pytest.mark.parametrize('input,expected_tag_names', [
@ -150,9 +150,9 @@ def test_order_by_implication_count(
tag2 = tag_factory(names=['t2'])
session.add_all([sug1, sug3, tag2, sug2, tag1])
session.commit()
tag1.implications.append(db.TagImplication(tag1.tag_id, sug1.tag_id))
tag1.implications.append(db.TagImplication(tag1.tag_id, sug2.tag_id))
tag2.implications.append(db.TagImplication(tag2.tag_id, sug3.tag_id))
tag1.implications.append(sug1)
tag1.implications.append(sug2)
tag2.implications.append(sug3)
verify_unpaged(input, expected_tag_names)
def test_filter_by_relation_count(session, verify_unpaged, tag_factory):

View file

@ -36,10 +36,10 @@ def export_to_json(session):
}
if len(tag.suggestions):
item['suggestions'] = \
[rel.child_tag.names[0].name for rel in tag.suggestions]
[rel.names[0].name for rel in tag.suggestions]
if len(tag.implications):
item['implications'] = \
[rel.child_tag.names[0].name for rel in tag.implications]
[rel.names[0].name for rel in tag.implications]
output.append(item)
export_path = os.path.join(config.config['data_dir'], 'tags.json')
with open(export_path, 'w') as handle:
@ -131,15 +131,11 @@ def update_implications(session, tag, relations):
raise RelationError('Tag cannot imply itself.')
related_tags, new_tags = get_or_create_by_names(session, relations)
session.flush()
tag.implications = [
db.TagImplication(tag.tag_id, other_tag.tag_id) \
for other_tag in related_tags + new_tags]
tag.implications = related_tags + new_tags
def update_suggestions(session, tag, relations):
if _check_name_intersection(_get_plain_names(tag), relations):
raise RelationError('Tag cannot suggest itself.')
related_tags, new_tags = get_or_create_by_names(session, relations)
session.flush()
tag.suggestions = [
db.TagSuggestion(tag.tag_id, other_tag.tag_id) \
for other_tag in related_tags + new_tags]
tag.suggestions = related_tags + new_tags