Python Flask API:如何从sqlalchemy联接的结果集发回选择性列
我正在尝试执行一个简单的代码片段来打印3表联接查询的结果。我正在使用python/flask restplus/sqlalchemy 以下是我的例子:Python Flask API:如何从sqlalchemy联接的结果集发回选择性列,python,flask,sqlalchemy,flask-sqlalchemy,flask-restplus,Python,Flask,Sqlalchemy,Flask Sqlalchemy,Flask Restplus,我正在尝试执行一个简单的代码片段来打印3表联接查询的结果。我正在使用python/flask restplus/sqlalchemy 以下是我的例子: class Users(db.Model): id = db.Column(db.Integer, db.Sequence('users_id_seq'), primary_key=True) email = db.Column(db.String(64), unique=True, nullable=False) pas
class Users(db.Model):
id = db.Column(db.Integer, db.Sequence('users_id_seq'), primary_key=True)
email = db.Column(db.String(64), unique=True, nullable=False)
password = db.Column(db.String(128), nullable=False)
created = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
expires = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
rights = db.relationship('Rights', backref='user', lazy=True)
def __repr__(self):
return '<Users %r>' % self.email
class Applications(db.Model):
id = db.Column(db.Integer, db.Sequence('applications_id_seq'), primary_key=True)
code = db.Column(db.String(5), unique=True, nullable=False)
name = db.Column(db.String(128), nullable=False)
rights = db.relationship('Rights', backref='application', lazy=True)
def __repr__(self):
return '<Applications %r>' % self.code
class Rights(db.Model):
id = db.Column(db.Integer, db.Sequence('rights_id_seq'), primary_key=True)
role = db.Column(db.String(16), nullable=False)
app_id = db.Column(db.Integer, db.ForeignKey('applications.id'), nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
def __repr__(self):
return '<Rights %r>' % self.role
db.drop_all()
db.create_all()
user1 = Users(email='user1@example.com', password='password1')
user2 = Users(email='user2@example.com', password='password2')
user3 = Users(email='user3@example.com', password='password3')
appli1 = Applications(code='APP1', name='Appli 1')
appli2 = Applications(code='APP2', name='Appli 2')
appli3 = Applications(code='APP3', name='Appli 3')
db.session.add(user1)
db.session.add(user2)
db.session.add(user3)
db.session.add(appli1)
db.session.add(appli2)
db.session.add(appli3)
u1=Users.query.get(1)
a1=Applications.query.get(1)
rights1 = Rights(role='MANAGER', application=a1, user=u1)
db.session.add(rights1)
a2=Applications.query.get(2)
rights2 = Rights(role='USER', application=a2, user=u1)
db.session.add(rights2)
u2=Users.query.get(2)
rights3 = Rights(role='MANAGER', application=a2, user=u2)
db.session.add(rights3)
u3=Users.query.get(3)
a3=Applications.query.get(3)
rights4 = Rights(role='USER', application=a1, user=u3)
rights5 = Rights(role='USER', application=a2, user=u3)
rights6 = Rights(role='USER', application=a3, user=u3)
db.session.add(rights4)
db.session.add(rights5)
db.session.add(rights6)
db.session.commit()
nsmanage = api.namespace('manage', description='Api Management Related Operations')
rightresp = api.model('Rights_Response', {
'email': fields.String(required=True, description='Login/Email'),
'role': fields.String(required=True, description='[user|admin|appmanager]'),
'code': fields.String(required=True, description='3-letter app code')
})
@nsmanage.route('/rights/<string:email>')
@nsmanage.param('email', "User's Email")
@nsmanage.response(404, 'User not found')
class GetRightsByEmail(Resource):
@nsmanage.marshal_with(rightresp)
def get(self, email):
'''Fetch a user's rights given its email'''
query = Rights.query.join(Applications, Users).options(contains_eager('user'),contains_eager('application')).filter(Users.email == email).all()
for i in query:
print (i.role,i.user.email,i.application.code)
return query
api.abort(404, message="User {} not found".format(email))
这显然不是我想要的。
查询正常,因为行返回查询之前的for循环打印正确答案:
MANAGER user1@example.com APP1
USER user1@example.com APP2
我与marshal_一起使用的rightresp模型在查询中找到了正确的列
我相信这是一个新问题,我是,但我不知道如何发送回正确的答案使用api,即:
[
{
"email": "user1@example.com",
"role": "MANAGER",
"code": "APP1"
},
{
"email": "user1@example.com",
"role": "USER",
"code": "APP2"
}
]
非常感谢。
洛朗
编辑:
在数据库中,生成的查询正常连接正常,并且选择了我想要的列:
SELECT rights.id AS rights_id,
rights.role AS rights_role,
rights.app_id AS rights_app_id,
rights.user_id AS rights_user_id,
users.id AS users_id,
users.email AS users_email,
users.password AS users_password,
users.created AS users_created,
users.expires AS users_expires,
applications.id AS applications_id,
applications.code AS applications_code,
applications.name AS applications_name
FROM rights JOIN applications ON applications.id = rights.app_id
JOIN users ON users.id = rights.user_id
WHERE users.email = :email_1
您对电子邮件和代码的查询不会返回字符串,而是返回类User和应用程序的实例。我不熟悉马歇尔,所以我不太了解那里的情况。您可能希望将查询更改为:
user = User.query.filter_by(email=email).first()
您可以通过user.rights访问其权限,并通过user.rights[index].app\u id访问其应用程序
然后,您可能希望循环它们的权限,并将它们添加到字典中,然后发回该字典的jsonified版本或类似的内容 基于Joost answer,我将代码修改为以下内容,并且代码正常工作:
def get(self, email):
'''Fetch a user's rights given its email'''
query = Rights.query.join(Applications, Users).options(contains_eager('user'),contains_eager('application')).filter(Users.email == email).all()
response = []
for i in query:
print (i.role,i.user.email,i.application.code)
info = {
"email": i.role,
"role": i.user.email,
"code": i.application.code,
}
response.append(info)
print (response)
return response, 200
api.abort(404, message="User {} not found".format(email))
如果我使用您的查询,则在数据库中,查询将更改为:选择users\u id、users\u email、users\u password、users\u created、users\u expires FROM选择users.id作为users\u id、users.email作为users\u email、users.password作为users\u password、users.created作为users\u created,users.expires AS users\u expires FROM users WHERE.email=:email\u 1 WHERE ROWNUM我通过我的查询获得了正确的信息:query=Rights.query.joinApplications,users.options包含渴望的“user”,包含渴望的“application”。filterUsers.email==email.all for I in query:print I.role,I.user.email,i、 application.code这里我缺少的是您所说的:循环他们的权限,并将它们添加到字典中,然后发回该字典的jsonified版本。您能提供一个示例吗?
def get(self, email):
'''Fetch a user's rights given its email'''
query = Rights.query.join(Applications, Users).options(contains_eager('user'),contains_eager('application')).filter(Users.email == email).all()
response = []
for i in query:
print (i.role,i.user.email,i.application.code)
info = {
"email": i.role,
"role": i.user.email,
"code": i.application.code,
}
response.append(info)
print (response)
return response, 200
api.abort(404, message="User {} not found".format(email))