def import_students(upload): """ Importer Statistics from file. Additionally imports all new object, which will be found. :param upload: :return: """ success = False try: # check format header = upload.file.readline().decode() assert header.startswith(HEADER) except: header = None if header: session = create_session() subject_ids = [] # collect existing objects and map it for subject in header.replace(HEADER, '').split(','): obj, new = get_or_create_by_required(Subject, name=subject) subject_ids.append(obj.id) statistics = {(x.student_id, x.room_id, x.quarter_id, x.subject_id): x for x in session.query(Statistic).filter( Statistic.subject_id.in_(subject_ids)).all()} students = {(x.name, x.birth): x.id for x in session.query(Student).all()} quarters = {(x.year, x.quarter): x.id for x in session.query(Quarter).all()} rooms = {x.name: x.id for x in session.query(Room).all()} # look at new row from the file nextline = upload.file.readline() while nextline: fields = nextline.decode().replace('\n', '').split(',') _id, name, birth, room, year, quarter = fields[:6] birth = datetime.datetime.strptime(birth, "%d/%m/%Y").date() year = int(year) stats = fields[6:] if room in rooms: room_id = rooms[room] else: obj = Room(name=room) session.add(obj) session.flush() room_id = obj.id rooms[room] = room_id student_key = (name, birth) if student_key in students: student_id = students[student_key] else: obj = Student(name=name, birth=birth) session.add(obj) session.flush() student_id = obj.id students[student_key] = student_id quarter_key = (year, quarter) if quarter_key in quarters: quarter_id = quarters[quarter_key] else: obj = Quarter(year=year, quarter=quarter) session.add(obj) session.flush() quarter_id = obj.id quarters[quarter_key] = quarter_id # look at every subject column for subject_id, value in itertools.zip_longest(subject_ids, stats): value = int(value) statistic_key = (student_id, room_id, quarter_id, subject_id) if statistic_key in statistics: obj = statistics[statistic_key] if obj.value != value: obj.value = value session.flush() else: obj = Statistic(student_id=student_id, room_id=room_id, quarter_id=quarter_id, subject_id=subject_id, value=value) session.add(obj) session.flush() # commit new row objects session.commit() nextline = upload.file.readline() success = True return success