diff --git a/README.md b/README.md index e37ca57..80846be 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ Run application and init database ```bash docker-compose up -d --build docker-compose exec backend flask db upgrade +docker-compose exec backend flask init_db ``` Turn off application diff --git a/backend/app/__init__.py b/backend/app/__init__.py index 8795b6e..a4edeea 100644 --- a/backend/app/__init__.py +++ b/backend/app/__init__.py @@ -7,6 +7,7 @@ from flask_cors import CORS from .config import config from .dependencies import db, ma from .commands.startapp import startapp +from .commands.init_db import init_db from .utils import import_models from .api import api_bp from .errors import request_entity_too_large, register_error_handlers @@ -35,6 +36,7 @@ def create_app(config_name: str = None) -> APIFlask: # register commands app.cli.add_command(startapp) + app.cli.add_command(init_db) # register errors register_error_handlers(app) diff --git a/backend/app/commands/init_db.py b/backend/app/commands/init_db.py new file mode 100644 index 0000000..cb28c6f --- /dev/null +++ b/backend/app/commands/init_db.py @@ -0,0 +1,37 @@ +from flask.cli import with_appcontext +from click import command + +from ..dependencies import db +from ..factory import ProjectSupervisorFactory, GroupFactory, StudentFactory + + +@command('init_db') +@with_appcontext +def init_db() -> None: + """Fill database with some data""" + db.drop_all() + db.create_all() + + num_of_supervisors = 5 + + projects_supervisors = [ProjectSupervisorFactory() for _ in range(num_of_supervisors)] + db.session.add_all(projects_supervisors) + db.session.commit() + + groups = [GroupFactory(project_supervisor=projects_supervisors[i]) for i in range(num_of_supervisors)] + db.session.add_all(groups) + db.session.commit() + + num_of_students = num_of_supervisors * 3 + students = [StudentFactory(group=groups[i % num_of_supervisors]) for i in range(num_of_students)] + + max_count = 10 + max_length = len(students) + start_count = 0 + + while True: + if start_count > max_length: + break + db.session.add_all(students[start_count:max_count]) + db.session.commit() + start_count += max_count diff --git a/backend/app/factory.py b/backend/app/factory.py new file mode 100644 index 0000000..a60bf5f --- /dev/null +++ b/backend/app/factory.py @@ -0,0 +1,43 @@ +from factory import alchemy, Sequence, RelatedFactory, LazyAttribute +from factory.faker import Faker +from factory.fuzzy import FuzzyInteger, FuzzyChoice + +from .dependencies import db +from .students.models import Student, Group, ProjectSupervisor + + +class ProjectSupervisorFactory(alchemy.SQLAlchemyModelFactory): + class Meta: + model = ProjectSupervisor + sqlalchemy_session = db.session + + first_name = Faker('first_name') + last_name = Faker('last_name') + email = Faker('email') + limit_group = 4 # FuzzyInteger(3, 5) + count_groups = 4 + mode = FuzzyChoice([True, False]) + + +class GroupFactory(alchemy.SQLAlchemyModelFactory): + class Meta: + model = Group + sqlalchemy_session = db.session + + name = Sequence(lambda n: f'Group-{n}') + # project_supervisor = RelatedFactory(ProjectSupervisorFactory, 'project_supervisor') + + +class StudentFactory(alchemy.SQLAlchemyModelFactory): + class Meta: + model = Student + sqlalchemy_session = db.session + + first_name = Faker('first_name') + last_name = Faker('last_name') + email = Faker('email') + index = Sequence(lambda n: 400_000 + n) + first_term = FuzzyInteger(1, 5) + second_term = FuzzyInteger(1, 5) + # group = RelatedFactory(GroupFactory) + mode = FuzzyChoice([True, False]) diff --git a/backend/app/students/models.py b/backend/app/students/models.py index cc8d6c9..1e2117c 100644 --- a/backend/app/students/models.py +++ b/backend/app/students/models.py @@ -10,6 +10,7 @@ class ProjectSupervisor(Base, Person): __tablename__ = "project_supervisors" limit_group = db.Column(db.Integer, default=1, nullable=False) + count_groups = db.Column(db.Integer, default=1) mode = db.Column(db.Boolean, default=True, nullable=False) # True - stationary, False - non-stationary diff --git a/backend/migrations/versions/985c8a17dd66_.py b/backend/migrations/versions/985c8a17dd66_.py new file mode 100644 index 0000000..bd1cf1e --- /dev/null +++ b/backend/migrations/versions/985c8a17dd66_.py @@ -0,0 +1,28 @@ +"""empty message + +Revision ID: 985c8a17dd66 +Revises: 84d4066483b8 +Create Date: 2022-06-07 16:44:52.514825 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '985c8a17dd66' +down_revision = '84d4066483b8' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('project_supervisors', sa.Column('count_groups', sa.Integer(), nullable=True)) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('project_supervisors', 'count_groups') + # ### end Alembic commands ### diff --git a/backend/requirements.txt b/backend/requirements.txt index dda2589..d956d69 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -36,3 +36,4 @@ tomli==2.0.1 Werkzeug==2.1.2 zipp==3.8.0 apiflask==1.0.2 +factory_boy==3.2.1 \ No newline at end of file