В Flask REST API нужно ли мне создавать разные модели и ресурсы для работы с разными строками одной и той же таблицы?

#python-3.x #rest #flask-sqlalchemy #flask-restful

#python-3.x #rest #flask-sqlalchemy #flask-restful

Вопрос:

Я новичок в API и создаю FLask Restful API.Мне было интересно, нужно ли мне создавать новые классы моделей и ресурсов для любых манипуляций со строками, которые я хочу выполнить в своей БД? Например, я создал student в своей базе данных. При создании у него нет никаких оценок, поэтому я создал StudentModel и StudentResource и использовал таблицу Student. Когда мне нужно обновить оценки с помощью запроса PUT, нужно ли мне создавать SudentGradeModel и StudentGradeResource, также обращающиеся к таблице student?

Каждый класс модели включает вспомогательные функции, которые класс ресурсов использует при импорте класса модели. Классы ресурсов имеют только методы GET, POST, PUT и DELETE.

 class StudentModel(db.Model):
    __tablename__ = 'Student'
    __table_args__ = {'extend_existing': True}

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(30))
    class_sec = db.Column(db.String(4))
    
    def __init__(self, id, name, class_sec):
        self.id = id
        self.name= name
        self.class_sec = class_sec    

  
 from flask_restful import Resource, reqparse

from models.student_model import StudenteModel


# noinspection PyMethodMayBeStatic
class StudentResource(Resource):

    parser = reqparse.RequestParser()
    parser.add_argument('id', type=int, required=True, help='Every Student must have an ID')
    parser.add_argument('name', type=str, required=True, help='Every Student must have a name')
    parser.add_argument('class', type=str, required=True, help='Every Student must be assigned a class and section')

    def get(self, id):
        pass

    def post(self, id):
        pass

  
 class StudentGradeModel(db.Model):
    __tablename__ = 'Student'
    __table_args__ = {'extend_existing': True}

    id = db.Column(db.Integer, primary_key=True)
    grade = db.Column(db.String(2), primary_key=True)
    
    def __init__(self, id, grade):
        self.id = id
        self.grade = grade
  
 # noinspection PyMethodMayBeStatic
class StudentGradeResource(Resource):

    parser = reqparse.RequestParser()
    parser.add_argument('id', type=int, required=True, help='Student must have an ID to access table')
    parser.add_argument('grade', type=str, required=True, help='Student must have a grade to be assigned')

    def get(self, id):
        pass

    def post(self, id):
        pass
  

Аналогично, если бы я хотел обновить только раздел, мне пришлось бы создавать аналогичный класс с запросом PUT.

Спасибо

Ответ №1:

Исходя из вопроса, я предполагаю, что у одного ученика может быть только одна оценка или ее вообще не быть, потому что, если у них может быть больше одной, оценка должна быть в отдельной таблице.

SQL для создания таблицы выглядит следующим образом:

 CREATE TABLE student (
  id INT PRIMARY KEY,
  name VARCHAR(30) NOT NULL,
  class_sec CHAR(4) NOT NULL,
  grade INTEGER
);
  

(Я изменил тип данных для grade, поскольку числовые данные не должны храниться в виде строки)


Нет, вы не можете и не должны иметь две модели для одной и той же таблицы. Модель должна представлять саму таблицу.

 class StudentModel(db.Model):
    __tablename__ = 'Student'
    __table_args__ = {'extend_existing': True}

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(30), nullable=False)
    class_sec = db.Column(db.String(4), nullable=False)
    grade = db.Column(db.Integer)
    
    def __init__(self, id, name, class_sec):
        self.id = id
        self.name= name
        self.class_sec = class_sec
  

С другой стороны, у вас может быть более одного ресурса для взаимодействия с таблицей. Однако каждый ресурс связан с одним маршрутом, и у вас не должно быть отдельного ресурса для оценки, если только вам не нужен другой маршрут для этого, чего, я думаю, у вас нет.

 class Student(Resource):
    ...
    def put(self, id):
        request_body = request.get_json()
        # do your things here
  

Комментарии:

1. Большое спасибо за ответ. Я понимаю вашу точку зрения, но я немного сбит с толку. Поскольку вы предположили, что мне не нужен другой ресурс для оценки, должен ли я указать условия if else в методе put и решить, что делать? Также, когда я должен создать новый ресурс?

2. @Hassan Обычно запрос PUT выглядит следующим образом PUT /student/<id>/ body { name: «Joe» grade: 8 } Тогда имя будет обновлено до Joe, а оценка будет обновлена до 8. Условия не нужны. В python это можно сделать с помощью update встроенной функции, которая обновляет словари.

3. Вам нужен другой ресурс, когда у вас есть этот ресурс на другом маршруте. Например, у вас может быть resource StudentList в /students / и StudentInfo в / students /<id>

4. Это действительно прояснило мое замешательство. Большое спасибо за вашу помощь.