I am using Flask-Restplus and SQLAlchemy to develop my API. I want to return a response with information from two SQAlchemy objects, a user and a device, with a 1:1 relationship between them.
I have a query that looks like this:
details = db.session.query(User, Device).filter(User.id == Device.id) \
.filter(User.email== data['email'])\
.all()
For now, the result of the query above can be printed in console is like this:
[(<User 'None'>, <Device 1>)]
I want my API endpoint to return the following JSON:
{
"data": [
[
{
"id": 20,
"name": null,
"token": "Some String here"
}
]
]
}
Here is my DTO:
class UserDto:
# this is for input
user = api.model('user', {
'email': fields.String(required=False, description='phone number'),
'name': fields.String(required=False, description='username'),
'device_id': fields.String(required=False,description='user_device_id'),
})
# this is for output
details = api.model('details', {
'id': fields.Integer(required=False, description='the id'),
'name': fields.String(required=False, description='name'),
'token': fields.String(required=False, description='token')
})
Models for User
and Device
:
class User(db.Model):
__tablename__ = "users_info"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.Integer, unique=True, nullable=True)
email = db.Column(db.String)
device = db.relationship('Device', backref='user')
# .. more fields ..
class Device(db.Model):
__tablename__ = "user_device"
user_device_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
id = db.Column(db.Integer, db.ForeignKey(User.id))
token = db.Column(db.String, nullable=True)
# .. more fields ..
I order to achieve JSON result above, I want the id
and name
is from the User
object, and token
is from the Device
object.
Controller:
api = UserDto.api
_user = UserDto.user
_details = UserDto.details
@api.route('/')
class User(Resource):
@api.response(201, 'successful')
@api.expect(_user, validate=True)
@api.marshal_list_with(_details, envelope='data')
def post(self):
data = request.json
return user(data=data)
Actual Response:
{
"data": [
[
{
"id": 20,
"name": null,
"token": null
},
{
"id": 20,
"name": null,
"token": "some string here"
}
]
]
}
As you can see here, the same record appears 2 twice (once with token
being null
and once with token
with the string I want).
How can I achieve the response that I want above?