我正在使用Python库flask-rest-jsonapi设计API。该库使用flask-sqlalchemy和marshmallow。棉花糖要求架构中必须包含一个“ id”和一个“ type”字段。
我要为其设计API的数据库表没有“ id”列。我要定义关系的两个表称为“部门和教师”,其中一个部门有多名教师,因此部门与教师之间存在一对多的关系。它们的主键列称为“ Department_Unique_ID”和“ Teacher_Unique_ID”。
这是我的代码:
from flask import Flask
from flask_rest_jsonapi import Api, ResourceDetail, ResourceList, ResourceRelationship
from flask_rest_jsonapi.exceptions import ObjectNotFound
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.orm.exc import NoResultFound
from marshmallow_jsonapi.flask import Schema, Relationship
from marshmallow_jsonapi import fields
import connectDB
# Create the Flask application
app = Flask(__name__)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app = connectDB.connectToDb(app)
db = SQLAlchemy(app)
class Department(db.Model):
db.Model.metadata.schema = 'UNIVERSITY'
__tablename__ = 'Department'
Department_Unique_ID = db.Column(db.String, primary_key=True)
Department_Name = db.Column(db.String)
uni_teacher = db.relationship('Teacher', backref=db.backref('Department'))
__mapper_args__ = {
"order_by":Department_Unique_ID
}
class Teacher(db.Model):
db.Model.metadata.schema = 'UNIVERSITY'
__tablename__ = 'Teacher'
Teacher_Unique_ID = db.Column(db.String, primary_key=True)
Teacher_Name = db.Column(db.String)
Department_ID_Unique = db.Column(db.String, db.ForeignKey('Department.Department_Unique_ID'))
__mapper_args__ = {
"order_by":Teacher_Unique_ID
}
class DepartmentSchema(Schema):
class Meta:
type_ = 'uni_department'
self_view = 'uni_department_detail'
self_view_kwargs = {'id': '<Department_Unique_ID>'}
self_view_many = 'uni_department_list'
strict = True
__model__ = Department
id = fields.Integer(as_string=True, many=True, dump_only=True) #not used, if I remove this, I get an error "Must have an 'id' field"
Department_Unique_ID = fields.Str()
Department_Name = fields.Str()
uni_teacher = Relationship(self_view='uni_department_uni_teacher',
self_view_kwargs={'id':'<Department_Unique_ID>'},
related_view='uni_teacher_list',
related_view_kwargs={'id':'<Department_Unique_ID>'},
many=True,
schema='TeacherSchema',
type_='uni_teacher',
id_field='Teacher_Unique_ID')
class TeacherSchema(Schema):
class Meta:
type_ = 'uni_teacher'
self_view = 'uni_teacher_detail'
self_view_kwargs = {'id': '<Teacher_Unique_ID>'}
self_view_many = 'uni_teacher_list'
strict = True
__model__ = Teacher
id = fields.Integer(as_string=True, many=True, dump_only=True) #not used, if I remove this, I get an error "Must have an 'id' field"
Teacher_Unique_ID = fields.Str()
Teacher_Name = fields.Str()
owner = Relationship(attribute='uni_department',
self_view='uni_teacher_uni_department',
self_view_kwargs={'id':'<Teacher_Unique_ID>'},
related_view='uni_department_detail',
related_view_kwargs={'id':'<Department_Unique_ID>'},
schema='DepartmentSchema',
type_='uni_department')
class DepartmentList(ResourceList):
schema = DepartmentSchema
data_layer = {'session': db.session,
'model': Department}
class TeacherList(ResourceList):
def query(self, view_kwargs):
query_ = self.session.query(Teacher)
if view_kwargs.get('Teacher_Unique_ID') is not None:
try:
self.session.query(Department).filter_by(Teacher_Unique_ID=view_kwargs['Teacher_Unique_ID']).one()
except NoResultFound:
raise ObjectNotFound({'parameter': 'Teacher_Unique_ID'}, "Teacher: {} not found".format(view_kwargs['Teacher_Unique_ID']))
else:
query_ = query_.join(Department).filter(Department.id == view_kwargs['Teacher_Unique_ID'])
return query_
def before_create_object(self, data, view_kwargs):
if view_kwargs.get('Teacher_Unique_ID') is not None:
uni_department = self.session.query(Department).filter_by(Teacher_Unique_ID=view_kwargs['Department_Unique_ID']).one()
data['Department_Unique_ID'] = uni_department.Department_Unique_ID
schema = TeacherSchema
data_layer = {'session': db.session,
'model': Teacher}
class DepartmentDetail(ResourceDetail):
def before_get_object(self, view_kwargs):
if view_kwargs.get('Teacher_Unique_ID') is not None:
try:
uni_teacher = self.session.query(Teacher).filter_by(Department_Unique_ID=view_kwargs['Department_Unique_ID']).one()
except NoResultFound:
raise ObjectNotFound({'parameter': 'Department_Unique_ID'},
"Teacher: {} not found".format(view_kwargs['Department_Unique_ID']))
else:
if uni_teacher.uni_department is not None:
view_kwargs['Department_Unique_ID'] = uni_teacher.uni_department.Department_Unique_ID
else:
view_kwargs['Department_Unique_ID'] = None
schema = DepartmentSchema
data_layer = {'session': db.session,
'model': Department}
class TeacherDetail(ResourceDetail):
schema = TeacherSchema
data_layer = {'session': db.session,
'model': Teacher}
class DepartmentRelationship(ResourceRelationship):
schema = DepartmentSchema
data_layer = {'session': db.session,
'model': Department}
class TeacherRelationship(ResourceRelationship):
schema = TeacherSchema
data_layer = {'session': db.session,
'model': Teacher}
api = Api(app)
api.route(DepartmentList, 'uni_department_list', '/uni_department')
api.route(TeacherList, 'uni_teacher_list', '/uni_teacher', '/uni_teacher/<int:Department_Unique_ID>/uni_teacher')
api.route(DepartmentDetail, 'uni_department_detail', '/uni_department/<int:Department_Unique_ID>', '/uni_teacher/<int:Department_ID_Unique>/owner')
api.route(TeacherDetail, 'uni_teacher_detail', '/uni_teacher/<int:Teacher_Unique_ID>')
api.route(DepartmentRelationship, 'uni_department_uni_teacher', '/uni_department/<int:Department_Unique_ID>/relationships/uni_teacher')
api.route(TeacherRelationship, 'uni_teacher_uni_department', '/uni_teacher/<int:Teacher_Unique_Department>/relationships/owner')
if __name__ == '__main__':
# Start application
app.debug = True
app.run()
我正在遵循flask-rest-jsonapi中的示例。任何帮助将不胜感激。
EDIT1-这是所请求的connectDB.py代码-
import yaml
def readDbDetails():
with open('database_config.yaml', 'r') as stream:
return (yaml.load(stream))
dbDetails = readDbDetails()
def connectToDb(app):
database_host = dbDetails['database_host']
database_username = dbDetails['database_username']
database_name = dbDetails['database_name']
database_password = dbDetails['database_password']
database_port = dbDetails['database_port']
print(database_host)
print(database_name)
print(database_username)
print(database_password)
print(database_port)
app.config[
'SQLALCHEMY_DATABASE_URI'] = 'mssql+pymssql://'+database_username+':'+database_password+'@'+database_host+':'+database_port+'/'+database_name+''
return app
答案 0 :(得分:0)
您可以使用属性属性,并将主键分配给该ID字段
class DepartmentSchema(Schema):
class Meta:
type_ = 'uni_department'
self_view = 'uni_department_detail'
self_view_kwargs = {'id': '<Department_Unique_ID>'}
self_view_many = 'uni_department_list'
strict = True
__model__ = Department
id = fields.Integer(attribute='Department_Unique_ID', as_string=True, many=True, dump_only=True)
Department_Unique_ID = fields.Str()
Department_Name = fields.Str()
uni_teacher = Relationship(self_view='uni_department_uni_teacher',
self_view_kwargs={'id': '<Department_Unique_ID>'},
related_view='uni_teacher_list',
related_view_kwargs={'id': '<Department_Unique_ID>'},
many=True,
schema='TeacherSchema',
type_='uni_teacher',
id_field='Teacher_Unique_ID')
class TeacherSchema(Schema):
class Meta:
type_ = 'uni_teacher'
self_view = 'uni_teacher_detail'
self_view_kwargs = {'id': '<Teacher_Unique_ID>'}
self_view_many = 'uni_teacher_list'
strict = True
__model__ = Teacher
id = fields.Integer(attribute='Teacher_Unique_ID', as_string=True, many=True, dump_only=True)
Teacher_Unique_ID = fields.Str()
Teacher_Name = fields.Str()
owner = Relationship(attribute='uni_department',
self_view='uni_teacher_uni_department',
self_view_kwargs={'id': '<Teacher_Unique_ID>'},
related_view='uni_department_detail',
related_view_kwargs={'id': '<Department_Unique_ID>'},
schema='DepartmentSchema',
type_='uni_department')