server/posts: fix relations bidirectionality
This commit is contained in:
parent
7488abb332
commit
b7f2982c9e
8 changed files with 48 additions and 33 deletions
|
@ -288,6 +288,9 @@ def import_post_relations(unused_post_ids, v1_session, v2_session):
|
||||||
v2_session.add(
|
v2_session.add(
|
||||||
db.PostRelation(
|
db.PostRelation(
|
||||||
parent_id=row['post1id'], child_id=row['post2id']))
|
parent_id=row['post1id'], child_id=row['post2id']))
|
||||||
|
v2_session.add(
|
||||||
|
db.PostRelation(
|
||||||
|
parent_id=row['post2id'], child_id=row['post1id']))
|
||||||
v2_session.commit()
|
v2_session.commit()
|
||||||
|
|
||||||
def import_post_favorites(unused_post_ids, v1_session, v2_session):
|
def import_post_favorites(unused_post_ids, v1_session, v2_session):
|
||||||
|
|
|
@ -112,16 +112,11 @@ class Post(Base):
|
||||||
# foreign tables
|
# foreign tables
|
||||||
user = relationship('User')
|
user = relationship('User')
|
||||||
tags = relationship('Tag', backref='posts', secondary='post_tag')
|
tags = relationship('Tag', backref='posts', secondary='post_tag')
|
||||||
relating_to = relationship(
|
relations = relationship(
|
||||||
'Post',
|
'Post',
|
||||||
secondary='post_relation',
|
secondary='post_relation',
|
||||||
primaryjoin=post_id == PostRelation.parent_id,
|
primaryjoin=post_id == PostRelation.parent_id,
|
||||||
secondaryjoin=post_id == PostRelation.child_id, lazy='joined')
|
secondaryjoin=post_id == PostRelation.child_id, lazy='joined')
|
||||||
related_by = relationship(
|
|
||||||
'Post',
|
|
||||||
secondary='post_relation',
|
|
||||||
primaryjoin=post_id == PostRelation.child_id,
|
|
||||||
secondaryjoin=post_id == PostRelation.parent_id, lazy='joined')
|
|
||||||
features = relationship(
|
features = relationship(
|
||||||
'PostFeature', cascade='all, delete-orphan', lazy='joined')
|
'PostFeature', cascade='all, delete-orphan', lazy='joined')
|
||||||
scores = relationship(
|
scores = relationship(
|
||||||
|
|
|
@ -94,8 +94,7 @@ def serialize_post(post, authenticated_user, options=None):
|
||||||
{
|
{
|
||||||
post['id']:
|
post['id']:
|
||||||
post for post in [
|
post for post in [
|
||||||
serialize_micro_post(rel) \
|
serialize_micro_post(rel) for rel in post.relations
|
||||||
for rel in post.related_by + post.relating_to
|
|
||||||
]
|
]
|
||||||
}.values(),
|
}.values(),
|
||||||
key=lambda post: post['id']),
|
key=lambda post: post['id']),
|
||||||
|
@ -258,14 +257,24 @@ def update_post_tags(post, tag_names):
|
||||||
existing_tags, new_tags = tags.get_or_create_tags_by_names(tag_names)
|
existing_tags, new_tags = tags.get_or_create_tags_by_names(tag_names)
|
||||||
post.tags = existing_tags + new_tags
|
post.tags = existing_tags + new_tags
|
||||||
|
|
||||||
def update_post_relations(post, post_ids):
|
def update_post_relations(post, new_post_ids):
|
||||||
relations = db.session \
|
old_posts = post.relations
|
||||||
|
old_post_ids = [p.post_id for p in old_posts]
|
||||||
|
new_posts = db.session \
|
||||||
.query(db.Post) \
|
.query(db.Post) \
|
||||||
.filter(db.Post.post_id.in_(post_ids)) \
|
.filter(db.Post.post_id.in_(new_post_ids)) \
|
||||||
.all()
|
.all()
|
||||||
if len(relations) != len(post_ids):
|
if len(new_posts) != len(new_post_ids):
|
||||||
raise InvalidPostRelationError('One of relations does not exist.')
|
raise InvalidPostRelationError('One of relations does not exist.')
|
||||||
post.relating_to = relations
|
|
||||||
|
relations_to_del = [p for p in old_posts if p.post_id not in new_post_ids]
|
||||||
|
relations_to_add = [p for p in new_posts if p.post_id not in old_post_ids]
|
||||||
|
for relation in relations_to_del:
|
||||||
|
post.relations.remove(relation)
|
||||||
|
relation.relations.remove(post)
|
||||||
|
for relation in relations_to_add:
|
||||||
|
post.relations.append(relation)
|
||||||
|
relation.relations.append(post)
|
||||||
|
|
||||||
def update_post_notes(post, notes):
|
def update_post_notes(post, notes):
|
||||||
post.notes = []
|
post.notes = []
|
||||||
|
|
|
@ -16,7 +16,7 @@ def get_post_snapshot(post):
|
||||||
'checksum': post.checksum,
|
'checksum': post.checksum,
|
||||||
'tags': sorted([tag.first_name for tag in post.tags]),
|
'tags': sorted([tag.first_name for tag in post.tags]),
|
||||||
'relations': sorted([
|
'relations': sorted([
|
||||||
rel.post_id for rel in post.relating_to + post.related_by]),
|
rel.post_id for rel in post.relations]),
|
||||||
'notes': sorted([{
|
'notes': sorted([{
|
||||||
'polygon': note.polygon,
|
'polygon': note.polygon,
|
||||||
'text': note.text,
|
'text': note.text,
|
||||||
|
|
|
@ -97,8 +97,7 @@ class PostSearchConfig(BaseSearchConfig):
|
||||||
defer(db.Post.tag_count),
|
defer(db.Post.tag_count),
|
||||||
subqueryload(db.Post.tags).subqueryload(db.Tag.names),
|
subqueryload(db.Post.tags).subqueryload(db.Tag.names),
|
||||||
lazyload(db.Post.user),
|
lazyload(db.Post.user),
|
||||||
lazyload(db.Post.relating_to),
|
lazyload(db.Post.relations),
|
||||||
lazyload(db.Post.related_by),
|
|
||||||
lazyload(db.Post.notes),
|
lazyload(db.Post.notes),
|
||||||
lazyload(db.Post.favorited_by),
|
lazyload(db.Post.favorited_by),
|
||||||
)
|
)
|
||||||
|
|
|
@ -19,8 +19,8 @@ def test_saving_post(post_factory, user_factory, tag_factory):
|
||||||
post.user = user
|
post.user = user
|
||||||
post.tags.append(tag1)
|
post.tags.append(tag1)
|
||||||
post.tags.append(tag2)
|
post.tags.append(tag2)
|
||||||
post.relating_to.append(related_post1)
|
post.relations.append(related_post1)
|
||||||
post.relating_to.append(related_post2)
|
post.relations.append(related_post2)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
db.session.refresh(post)
|
db.session.refresh(post)
|
||||||
|
@ -33,12 +33,10 @@ def test_saving_post(post_factory, user_factory, tag_factory):
|
||||||
assert post.checksum == 'deadbeef'
|
assert post.checksum == 'deadbeef'
|
||||||
assert post.creation_time == datetime(1997, 1, 1)
|
assert post.creation_time == datetime(1997, 1, 1)
|
||||||
assert post.last_edit_time == datetime(1998, 1, 1)
|
assert post.last_edit_time == datetime(1998, 1, 1)
|
||||||
assert len(post.relating_to) == 2
|
assert len(post.relations) == 2
|
||||||
assert len(related_post1.relating_to) == 0
|
# relation bidirectionality is realized on business level in func.posts
|
||||||
assert len(related_post1.relating_to) == 0
|
assert len(related_post1.relations) == 0
|
||||||
assert len(post.related_by) == 0
|
assert len(related_post2.relations) == 0
|
||||||
assert len(related_post1.related_by) == 1
|
|
||||||
assert len(related_post1.related_by) == 1
|
|
||||||
|
|
||||||
def test_cascade_deletions(post_factory, user_factory, tag_factory):
|
def test_cascade_deletions(post_factory, user_factory, tag_factory):
|
||||||
user = user_factory()
|
user = user_factory()
|
||||||
|
@ -73,8 +71,8 @@ def test_cascade_deletions(post_factory, user_factory, tag_factory):
|
||||||
post.user = user
|
post.user = user
|
||||||
post.tags.append(tag1)
|
post.tags.append(tag1)
|
||||||
post.tags.append(tag2)
|
post.tags.append(tag2)
|
||||||
post.relating_to.append(related_post1)
|
post.relations.append(related_post1)
|
||||||
post.relating_to.append(related_post2)
|
post.relations.append(related_post2)
|
||||||
post.scores.append(score)
|
post.scores.append(score)
|
||||||
post.favorited_by.append(favorite)
|
post.favorited_by.append(favorite)
|
||||||
post.features.append(feature)
|
post.features.append(feature)
|
||||||
|
@ -83,7 +81,7 @@ def test_cascade_deletions(post_factory, user_factory, tag_factory):
|
||||||
|
|
||||||
assert not db.session.dirty
|
assert not db.session.dirty
|
||||||
assert post.user is not None and post.user.user_id is not None
|
assert post.user is not None and post.user.user_id is not None
|
||||||
assert len(post.relating_to) == 2
|
assert len(post.relations) == 2
|
||||||
assert db.session.query(db.User).count() == 1
|
assert db.session.query(db.User).count() == 1
|
||||||
assert db.session.query(db.Tag).count() == 2
|
assert db.session.query(db.Tag).count() == 2
|
||||||
assert db.session.query(db.Post).count() == 3
|
assert db.session.query(db.Post).count() == 3
|
||||||
|
|
|
@ -394,11 +394,22 @@ def test_update_post_relations(post_factory):
|
||||||
relation2 = post_factory()
|
relation2 = post_factory()
|
||||||
db.session.add_all([relation1, relation2])
|
db.session.add_all([relation1, relation2])
|
||||||
db.session.flush()
|
db.session.flush()
|
||||||
post = db.Post()
|
post = post_factory()
|
||||||
posts.update_post_relations(post, [relation1.post_id, relation2.post_id])
|
posts.update_post_relations(post, [relation1.post_id, relation2.post_id])
|
||||||
assert len(post.relating_to) == 2
|
assert len(post.relations) == 2
|
||||||
assert post.relating_to[0].post_id == relation1.post_id
|
assert post.relations[0].post_id == relation1.post_id
|
||||||
assert post.relating_to[1].post_id == relation2.post_id
|
assert post.relations[1].post_id == relation2.post_id
|
||||||
|
|
||||||
|
def test_relation_bidirectionality(post_factory):
|
||||||
|
relation1 = post_factory()
|
||||||
|
relation2 = post_factory()
|
||||||
|
db.session.add_all([relation1, relation2])
|
||||||
|
db.session.flush()
|
||||||
|
post = post_factory()
|
||||||
|
posts.update_post_relations(post, [relation1.post_id, relation2.post_id])
|
||||||
|
posts.update_post_relations(relation1, [])
|
||||||
|
assert len(post.relations) == 1
|
||||||
|
assert post.relations[0].post_id == relation2.post_id
|
||||||
|
|
||||||
def test_update_post_non_existing_relations():
|
def test_update_post_non_existing_relations():
|
||||||
post = db.Post()
|
post = db.Post()
|
||||||
|
|
|
@ -38,8 +38,8 @@ def test_serializing_post(post_factory, user_factory, tag_factory):
|
||||||
post.source = 'example.com'
|
post.source = 'example.com'
|
||||||
post.tags.append(tag1)
|
post.tags.append(tag1)
|
||||||
post.tags.append(tag2)
|
post.tags.append(tag2)
|
||||||
post.relating_to.append(related_post1)
|
post.relations.append(related_post1)
|
||||||
post.relating_to.append(related_post2)
|
post.relations.append(related_post2)
|
||||||
post.scores.append(score)
|
post.scores.append(score)
|
||||||
post.favorited_by.append(favorite)
|
post.favorited_by.append(favorite)
|
||||||
post.features.append(feature)
|
post.features.append(feature)
|
||||||
|
|
Loading…
Reference in a new issue