From 2f83e206e11550b8c72e532ffdaece736c411a5d Mon Sep 17 00:00:00 2001 From: Michael Weimann Date: Mon, 5 Jul 2021 20:39:49 +0200 Subject: [PATCH 1/2] implement searchtopics --- ki/actions/seed.py | 9 +- ki/handlers/update_profile.py | 28 ++++- ki/models.py | 16 +++ ki/test/test_profile_endpoint.py | 39 ++++++ .../808fe55111df_initial_migration.py | 118 ------------------ 5 files changed, 90 insertions(+), 120 deletions(-) delete mode 100644 migrations/versions/808fe55111df_initial_migration.py diff --git a/ki/actions/seed.py b/ki/actions/seed.py index f6d2976..81e9a31 100644 --- a/ki/actions/seed.py +++ b/ki/actions/seed.py @@ -6,7 +6,8 @@ import csv import logging from app import app, db -from ki.models import Address, Contact, ContactType, Language, Skill, Profile, ProfileLanguage, ProfileSkill, User +from ki.models import Address, Contact, ContactType, Language, Skill, Profile, ProfileLanguage, ProfileSearchtopic, \ + ProfileSkill, User def seed_contacttypes(): @@ -92,6 +93,12 @@ def seed(dev: bool): peters_php_skill = ProfileSkill(profile=peters_profile, skill_id=1, level=5) db.session.add(peters_php_skill) + peters_python_searchtopic = ProfileSearchtopic(profile=peters_profile, skill_id=3) + db.session.add(peters_python_searchtopic) + + peters_php_searchtopic = ProfileSearchtopic(profile=peters_profile, skill_id=1) + db.session.add(peters_php_searchtopic) + peter_de = ProfileLanguage(profile=peters_profile, language_id="de", level=5) db.session.add(peter_de) diff --git a/ki/handlers/update_profile.py b/ki/handlers/update_profile.py index 97480b6..ad70991 100644 --- a/ki/handlers/update_profile.py +++ b/ki/handlers/update_profile.py @@ -5,7 +5,8 @@ from flask import make_response, request from sqlalchemy import not_ -from ki.models import Address, Contact, ContactType, Language, User, Profile, ProfileLanguage, ProfileSkill, Skill +from ki.models import Address, Contact, ContactType, Language, User, Profile, ProfileLanguage, ProfileSearchtopic, \ + ProfileSkill, Skill from app import db @@ -71,6 +72,30 @@ def update_skills(profile, skills_data): not_(ProfileSkill.skill_id.in_(profile_skill_ids))).delete() +def update_searchtopics(profile, searchtopics_data): + profile_searchtopics_ids = [] + + for searchtopic_data in searchtopics_data: + skill_name = searchtopic_data["skill"]["name"] + skill = Skill.query.filter(Skill.name == skill_name).first() + + if (skill is None): + skill = Skill(name=skill_name) + db.session.add(skill) + + profile_searchtopic = ProfileSearchtopic.query.filter(ProfileSearchtopic.profile == profile, + ProfileSearchtopic.skill == skill).first() + + if (profile_searchtopic is None): + profile_searchtopic = ProfileSearchtopic(profile=profile, skill=skill) + db.session.add(profile_searchtopic) + + profile_searchtopics_ids.append(skill.id) + + ProfileSearchtopic.query.filter(ProfileSearchtopic.profile == profile, + not_(ProfileSearchtopic.skill_id.in_(profile_searchtopics_ids))).delete() + + def update_contacts(profile, contacts_data): contact_ids_to_be_deleted = list(map(lambda c: c.id, profile.contacts)) @@ -117,6 +142,7 @@ def update_profile(user_id: int): update_address(profile, request.json.get("address", {})) update_contacts(profile, request.json.get("contacts", {})) update_skills(profile, request.json.get("skills", {})) + update_searchtopics(profile, request.json.get("searchtopics")) update_languages(profile, request.json.get("languages", {})) db.session.commit() diff --git a/ki/models.py b/ki/models.py index afd5350..6abaf33 100644 --- a/ki/models.py +++ b/ki/models.py @@ -41,6 +41,7 @@ class Profile(db.Model): contacts = relationship("Contact") address = relationship("Address", uselist=False, back_populates="profile") skills = relationship("ProfileSkill", back_populates="profile") + searchtopics = relationship("ProfileSearchtopic", back_populates="profile") languages = relationship("ProfileLanguage", back_populates="profile") def to_dict(self): @@ -55,6 +56,7 @@ class Profile(db.Model): "address": self.address.to_dict(), "contacts": list(map(lambda contact: contact.to_dict(), self.contacts)), "skills": list(map(lambda skill: skill.to_dict(), self.skills)), + "searchtopics": list(map(lambda searchtopic: searchtopic.to_dict(), self.searchtopics)), "languages": list(map(lambda language: language.to_dict(), self.languages)) } @@ -137,6 +139,7 @@ class Skill(db.Model): name = Column(String(25), unique=True, nullable=False) profiles = relationship("ProfileSkill", back_populates="skill") + searchtopics = relationship("ProfileSearchtopic", back_populates="skill") def to_dict(self): return {"id": self.id, "name": self.name, "icon_url": "/skills/{}/icon".format(self.id)} @@ -156,6 +159,19 @@ class ProfileSkill(db.Model): return {"profile_id": self.profile_id, "skill": self.skill.to_dict(), "level": self.level} +class ProfileSearchtopic(db.Model): + __tablename__ = "profile_searchtopic" + + profile_id = Column(Integer, ForeignKey("profile.id"), primary_key=True) + skill_id = Column(Integer, ForeignKey("skill.id"), primary_key=True) + + profile = relationship("Profile", back_populates="searchtopics") + skill = relationship("Skill", back_populates="searchtopics") + + def to_dict(self): + return {"profile_id": self.profile_id, "skill": self.skill.to_dict()} + + class Language(db.Model): __tablename__ = "language" diff --git a/ki/test/test_profile_endpoint.py b/ki/test/test_profile_endpoint.py index 56638cd..03f18cf 100644 --- a/ki/test/test_profile_endpoint.py +++ b/ki/test/test_profile_endpoint.py @@ -71,6 +71,19 @@ class TestProfileEndpoint(ApiTest): }, "level": 5 }], + "searchtopics": [{ + "profile_id": 1, + "skill": { + "id": 3, + "name": "Python", + "icon_url": "/skills/3/icon" + } + }, { + "profile_id": 1, + "skill": { + "name": "Assembler" + } + }], "languages": [{ "id": 1, "language": { @@ -134,6 +147,17 @@ class TestProfileEndpoint(ApiTest): self.assertEqual(second_skill.skill.name, "Tschunkproduktion") self.assertEqual(second_skill.level, 5) + searchtopics = profile.searchtopics + self.assertEqual(len(searchtopics), 2) + + first_searchtopic = searchtopics[0] + self.assertEqual(first_searchtopic.skill.id, 3) + self.assertEqual(first_searchtopic.skill.name, "Python") + + second_searchtopic = searchtopics[1] + self.assertEqual(second_searchtopic.skill.id, 14) + self.assertEqual(second_searchtopic.skill.name, "Assembler") + languages = profile.languages self.assertEqual(len(languages), 2) @@ -216,6 +240,21 @@ class TestProfileEndpoint(ApiTest): }, "level": 3 }], + "searchtopics": [{ + "profile_id": 1, + "skill": { + "id": 1, + "name": "PHP", + "icon_url": "/skills/1/icon" + } + }, { + "profile_id": 1, + "skill": { + "id": 3, + "name": "Python", + "icon_url": "/skills/3/icon" + } + }], "languages": [{ "profile_id": 1, "language": { diff --git a/migrations/versions/808fe55111df_initial_migration.py b/migrations/versions/808fe55111df_initial_migration.py deleted file mode 100644 index e74b2ee..0000000 --- a/migrations/versions/808fe55111df_initial_migration.py +++ /dev/null @@ -1,118 +0,0 @@ -"""Initial migration. - -Revision ID: 808fe55111df -Revises: -Create Date: 2021-07-05 20:13:50.560579 - -""" -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision = '808fe55111df' -down_revision = None -branch_labels = None -depends_on = None - - -def upgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.create_table('contacttype', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('name', sa.String(length=25), nullable=False), - sa.PrimaryKeyConstraint('id') - ) - op.create_table('language', - sa.Column('id', sa.String(length=2), nullable=False), - sa.Column('name', sa.String(length=25), nullable=False), - sa.PrimaryKeyConstraint('id') - ) - op.create_table('profile', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('nickname', sa.String(length=25), nullable=False), - sa.Column('pronouns', sa.String(length=25), nullable=True), - sa.Column('volunteerwork', sa.String(length=4000), nullable=True), - sa.Column('freetext', sa.String(length=4000), nullable=True), - sa.Column('availability', sa.String(length=4000), nullable=True), - sa.Column('visible', sa.Boolean(), nullable=False), - sa.Column('created', sa.DateTime(), nullable=False), - sa.Column('updated', sa.DateTime(), nullable=False), - sa.PrimaryKeyConstraint('id'), - sa.UniqueConstraint('nickname') - ) - op.create_table('skill', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('name', sa.String(length=25), nullable=False), - sa.PrimaryKeyConstraint('id'), - sa.UniqueConstraint('name') - ) - op.create_table('address', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('name', sa.String(length=25), nullable=True), - sa.Column('street', sa.String(length=25), nullable=True), - sa.Column('house_number', sa.String(length=10), nullable=True), - sa.Column('additional', sa.String(length=25), nullable=True), - sa.Column('postcode', sa.String(length=10), nullable=True), - sa.Column('city', sa.String(length=25), nullable=True), - sa.Column('country', sa.String(length=25), nullable=True), - sa.Column('profile_id', sa.Integer(), nullable=False), - sa.ForeignKeyConstraint(['profile_id'], ['profile.id'], ), - sa.PrimaryKeyConstraint('id') - ) - op.create_table('contact', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('profile_id', sa.Integer(), nullable=False), - sa.Column('contacttype_id', sa.Integer(), nullable=False), - sa.Column('content', sa.String(length=200), nullable=False), - sa.ForeignKeyConstraint(['contacttype_id'], ['contacttype.id'], ), - sa.ForeignKeyConstraint(['profile_id'], ['profile.id'], ), - sa.PrimaryKeyConstraint('id') - ) - op.create_table('profile_language', - sa.Column('profile_id', sa.Integer(), nullable=False), - sa.Column('language_id', sa.Integer(), nullable=False), - sa.Column('level', sa.SmallInteger(), nullable=False), - sa.ForeignKeyConstraint(['language_id'], ['language.id'], ), - sa.ForeignKeyConstraint(['profile_id'], ['profile.id'], ), - sa.PrimaryKeyConstraint('profile_id', 'language_id') - ) - op.create_table('profile_skill', - sa.Column('profile_id', sa.Integer(), nullable=False), - sa.Column('skill_id', sa.Integer(), nullable=False), - sa.Column('level', sa.SmallInteger(), nullable=False), - sa.ForeignKeyConstraint(['profile_id'], ['profile.id'], ), - sa.ForeignKeyConstraint(['skill_id'], ['skill.id'], ), - sa.PrimaryKeyConstraint('profile_id', 'skill_id') - ) - op.create_table('user', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('auth_id', sa.String(length=50), nullable=False), - sa.Column('profile_id', sa.Integer(), nullable=True), - sa.ForeignKeyConstraint(['profile_id'], ['profile.id'], ), - sa.PrimaryKeyConstraint('id'), - sa.UniqueConstraint('auth_id') - ) - op.create_table('token', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('user_id', sa.Integer(), nullable=False), - sa.Column('token', sa.String(length=36), nullable=False), - sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), - sa.PrimaryKeyConstraint('id') - ) - # ### end Alembic commands ### - - -def downgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.drop_table('token') - op.drop_table('user') - op.drop_table('profile_skill') - op.drop_table('profile_language') - op.drop_table('contact') - op.drop_table('address') - op.drop_table('skill') - op.drop_table('profile') - op.drop_table('language') - op.drop_table('contacttype') - # ### end Alembic commands ### From 1b58c65666deb64c1d4811cf417f979a2a48981a Mon Sep 17 00:00:00 2001 From: Michael Weimann Date: Tue, 6 Jul 2021 21:19:58 +0200 Subject: [PATCH 2/2] fix migrations --- .../44b45a772abd_initial_migration.py | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 migrations/versions/44b45a772abd_initial_migration.py diff --git a/migrations/versions/44b45a772abd_initial_migration.py b/migrations/versions/44b45a772abd_initial_migration.py new file mode 100644 index 0000000..db8552e --- /dev/null +++ b/migrations/versions/44b45a772abd_initial_migration.py @@ -0,0 +1,126 @@ +"""Initial migration. + +Revision ID: 44b45a772abd +Revises: +Create Date: 2021-07-06 21:19:44.217722 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '44b45a772abd' +down_revision = None +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('contacttype', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('name', sa.String(length=25), nullable=False), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('language', + sa.Column('id', sa.String(length=2), nullable=False), + sa.Column('name', sa.String(length=25), nullable=False), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('profile', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('nickname', sa.String(length=25), nullable=False), + sa.Column('pronouns', sa.String(length=25), nullable=True), + sa.Column('volunteerwork', sa.String(length=4000), nullable=True), + sa.Column('freetext', sa.String(length=4000), nullable=True), + sa.Column('availability', sa.String(length=4000), nullable=True), + sa.Column('visible', sa.Boolean(), nullable=False), + sa.Column('created', sa.DateTime(), nullable=False), + sa.Column('updated', sa.DateTime(), nullable=False), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('nickname') + ) + op.create_table('skill', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('name', sa.String(length=25), nullable=False), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('name') + ) + op.create_table('address', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('name', sa.String(length=25), nullable=True), + sa.Column('street', sa.String(length=25), nullable=True), + sa.Column('house_number', sa.String(length=10), nullable=True), + sa.Column('additional', sa.String(length=25), nullable=True), + sa.Column('postcode', sa.String(length=10), nullable=True), + sa.Column('city', sa.String(length=25), nullable=True), + sa.Column('country', sa.String(length=25), nullable=True), + sa.Column('profile_id', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['profile_id'], ['profile.id'], ), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('contact', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('profile_id', sa.Integer(), nullable=False), + sa.Column('contacttype_id', sa.Integer(), nullable=False), + sa.Column('content', sa.String(length=200), nullable=False), + sa.ForeignKeyConstraint(['contacttype_id'], ['contacttype.id'], ), + sa.ForeignKeyConstraint(['profile_id'], ['profile.id'], ), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('profile_language', + sa.Column('profile_id', sa.Integer(), nullable=False), + sa.Column('language_id', sa.Integer(), nullable=False), + sa.Column('level', sa.SmallInteger(), nullable=False), + sa.ForeignKeyConstraint(['language_id'], ['language.id'], ), + sa.ForeignKeyConstraint(['profile_id'], ['profile.id'], ), + sa.PrimaryKeyConstraint('profile_id', 'language_id') + ) + op.create_table('profile_searchtopic', + sa.Column('profile_id', sa.Integer(), nullable=False), + sa.Column('skill_id', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['profile_id'], ['profile.id'], ), + sa.ForeignKeyConstraint(['skill_id'], ['skill.id'], ), + sa.PrimaryKeyConstraint('profile_id', 'skill_id') + ) + op.create_table('profile_skill', + sa.Column('profile_id', sa.Integer(), nullable=False), + sa.Column('skill_id', sa.Integer(), nullable=False), + sa.Column('level', sa.SmallInteger(), nullable=False), + sa.ForeignKeyConstraint(['profile_id'], ['profile.id'], ), + sa.ForeignKeyConstraint(['skill_id'], ['skill.id'], ), + sa.PrimaryKeyConstraint('profile_id', 'skill_id') + ) + op.create_table('user', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('auth_id', sa.String(length=50), nullable=False), + sa.Column('profile_id', sa.Integer(), nullable=True), + sa.ForeignKeyConstraint(['profile_id'], ['profile.id'], ), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('auth_id') + ) + op.create_table('token', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('user_id', sa.Integer(), nullable=False), + sa.Column('token', sa.String(length=36), nullable=False), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), + sa.PrimaryKeyConstraint('id') + ) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table('token') + op.drop_table('user') + op.drop_table('profile_skill') + op.drop_table('profile_searchtopic') + op.drop_table('profile_language') + op.drop_table('contact') + op.drop_table('address') + op.drop_table('skill') + op.drop_table('profile') + op.drop_table('language') + op.drop_table('contacttype') + # ### end Alembic commands ###