#python #postgresql #flask #sqlalchemy
#python #postgresql #flask #sqlalchemy
Вопрос:
Я пытаюсь обновить данные во внешнем интерфейсе, используя React / Redux из запроса PUT в серверной части flask / sqlalchemy / postgres. Моя проблема в том, что моя конечная точка может обновляться только по идентификатору, который бесполезен для интерфейса. Причина в том, что обновляемые данные взяты из класса отношений, который существует только для объединения двух других классов. Что мне нужно сделать, так это выяснить, как запрашивать и возвращать user_id и country_id, а не id . Кстати, я тестирую локально с помощью Postman. Модели для класса соединения (таблицы) следующие
class users_countries_join(db.Model):
id = db.Column(Integer, autoincrement=True, primary_key=True)
user_id = db.Column(Integer, ForeignKey(users.id), nullable=False)
country_id = db.Column(Integer, ForeignKey(countries.id), nullable=False)
status = db.Column(Integer, nullable=False)
notes = db.Column(TEXT, nullable=True)
user = db.relationship('users', backref='user_countries')
country = db.relationship('countries', backref='travelers')
def __init__(self, user_id, country_id, status, notes):
self.user_id = user_id
self.country_id = country_id
self.status = status
self.notes = notes
def __repr__(self):
return '<{}>' % self.__name__
Код для конечной точки:
@app.route('/api/mapview/<int:user_id>/<int:country_id>/<int:id>', methods=['PUT'])
def update_mapView_data(user_id, country_id, id):
user_country = users_countries_join.query.get(id)
user_country.user_id = request.json[‘user_id’]
user_country.country_id = request.json[‘country_id’]
user_country.status = request.json[‘status’]
user_country.notes = request.json[‘notes’]
db.session.commit()
return user_country_schema.jsonify(user_country)
Я пытался изменить конечную точку на приведенный ниже код, но это не работает. Теоретически, это то обновление, которое мне нужно. Тот, который обновляется путем доступа к данным через user_id и country_id, а не идентификатор класса. Я начинаю думать, что идентификатор не нужен для начала.
@app.route('/api/mapview/<int:user_id>/<int:country_id>', methods=['PUT'])
def update_mapView_data(user_id, country_id):
user_country = users_countries_join.query.get(user_id, country_id)
user_country.user_id = request.json[‘user_id’]
user_country.country_id = request.json[‘country_id’]
user_country.status = request.json[‘status’]
user_country.notes = request.json[‘notes’]
db.session.commit()
return user_country_schema.jsonify(user_country)
Может кто-нибудь указать мне правильное направление в том, как это сделать? Я надеюсь, что я просто усложняю это, чем это должно быть.
Комментарии:
1. В вашем случае я считаю, что SQLAlchemy. Больше подходит таблица, а не SQLAlchemy. Модель для
users_countries_join
.2. Спасибо за ваш комментарий, однако я установил рабочие отношения со всеми тремя классами, поэтому я не включил код для остальных. Я следил за документами для ORM, и это сработало прекрасно. Причина, по которой я использовал класс, а не таблицу для объединения, заключается в том, что у меня есть дополнительные поля помимо первичного ключа и внешних ключей. Вместо этого они предлагают вам использовать класс. На данный момент я пытаюсь найти способ получить user_id и country_id, а не идентификатор, и обновить их новой информацией.
Ответ №1:
Вы можете использовать метод filter_by() для фильтрации строк. Например, если вы хотите получить первый user_country, используя user_id и country_id, вы можете использовать следующий запрос:
user_country = users_countries_join.query.filter_by(user_id=user_id, country_id=country_id).first()
Если у вас более одной строки базы данных с одинаковым идентификатором пользователя или идентификатором страны:
user_country = users_countries_join.query.filter_by(user_id=user_id, country_id=country_id).all()
В вашем примере я предполагаю, что вы хотите получить только одну уникальную строку, чтобы вы могли использовать первый запрос.
Кроме того, после изменения значений свойств модели вы должны добавить это изменение в db.session:
db.session.add(user_country)
и фиксирует изменения в базе данных:
db.session.commit()
Я также хочу отметить, что вы должны использовать camel case при объявлении имени класса python, например UserCountry или только Cuntry, и для объединения двух моделей (таблиц) вы не должны определять те же атрибуты, которые у вас есть в классе User или классе Country. На мой взгляд, такой способ объединения двух таблиц является избыточным.