#python #sql #flask #sqlalchemy #flask-restplus
#python #sql #flask #sqlalchemy #flask-restplus
Вопрос:
Я пишу api с помощью Flask-RESTPlus и хочу сначала использовать базу данных sqlite в своем текущем коде:
Модели API
lightstate = api.model('LightState', {
'red': fields.Integer(description='red part of the rgb light'),
'green': fields.Integer(description='green part of the rgb light'),
'blue': fields.Integer(description='blue part of the rgb light'),
'bri': fields.Integer(description='brightness of the light')
})
lights = api.model('Lights', {
'id': fields.Integer(readOnly=True, description='The database id of the light'),
'name': fields.String(required=True, description='light name'),
'state': fields.Nested(lightstate)
})
Модель базы данных
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class Lights(db.Model):
__bind_key__ = 'lights'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(255))
red = db.Column(db.Integer)
green = db.Column(db.Integer)
blue = db.Column(db.Integer)
bri = db.Column(db.Integer)
def __init__(self, name, red, green, blue, bri):
self.name = name
self.red = red
self.green = green
self.blue = blue
self.bri = bri
Создать запись базы данных
def create_light(data):
name = data.get('name')
state = data.get('state')
red = state['red']
green = state['green']
blue = state['blue']
bri = state['bri']
entry = Lights(name, red, green, blue, bri)
db.add(entry)
Обработчик запроса
@namespace.route('/')
class Light(Resource):
@api.marshal_with(lights)
def get(self):
lights_data = Lights.query.all()
return lights_data
@api.expect(lights)
def post(self):
create_light(request.json)
return None, 200
Как вы можете видеть, я хочу сохранить имя, значения rbg и яркость источников света в базе данных. Запись базы данных с помощью post-запроса работает нормально.
Но результат запроса get выглядит следующим образом:
[
{
"id": 1,
"name": "garden",
"state": {
"red": null,
"green": null,
"blue": null,
"bri": null
}
},
{
"id": 2,
"name": "pool",
"state": {
"red": null,
"green": null,
"blue": null,
"bri": null
}
}
]
Как вы можете видеть, значения light равны нулю. Я знаю, что моя проблема связана с вложенными полями в определении моих моделей API, потому что, когда я помещаю все части в одну модель, это работает.
Измененная модель API
lights = api.model('Lights', {
'id': fields.Integer(readOnly=True, description='The database id of the light'),
'name': fields.String(required=True, description='light name'),
'red': fields.Integer(description='red part of the rgb light'),
'green': fields.Integer(description='green part of the rgb light'),
'blue': fields.Integer(description='blue part of the rgb light'),
'bri': fields.Integer(description='brightness of the light')
})
Вывод запроса get
[
{
"id": 1,
"name": "garden",
"red": 50,
"green": 205,
"blue": 50,
"bri": 84
},
{
"id": 2,
"name": "pool",
"red": 255,
"green": 0,
"blue": 255,
"bri": 96
}
]
Как я могу получить значения из моей базы данных в ключе «состояние»?
Комментарии:
1. Вы проверяли, установлены ли значения вообще в БД? Другими словами, что возвращает ваша БД при запуске
SELECT * FROM Lights
после отправки запроса post?2. Все значения заданы в БД. Смотрите мой последний пост «code». Это не проблема.
Ответ №1:
Я нашел ответ на этот вопрос, которым хочу поделиться.
Вам просто нужно добавить attribute=lambda x: x
в качестве аргумента вложенное поле модели api.
Полный пример:
lights = api.model('Lights', {
'id': fields.Integer(readOnly=True, description='The database id of the light'),
'name': fields.String(required=True, description='light name'),
'state': fields.Nested(lightstate, attribute=lambda x: x)
})