Flask RESTful - запрос SQLalchemy возвращает два списка - PullRequest
0 голосов
/ 14 января 2019

Я новичок в Python, в настоящее время я работаю над API групп ресторанов.

Проблема в том, что когда я соединяю две таблицы ресторанов и адреса, запрос SQLAlchemy отправляет мне 2 списка, однако я бы хотел объединить его списки

Я узнал о: https://docs.sqlalchemy.org/en/rel_1_1/orm/basic_relationships.html#many-to-many

мои два класса: рестораны и адреса

restaurant_adresse_association = db.Table(
   'restaurant_adresse',
    db.Column('restaurant_id', db.Integer, ForeignKey('restaurants.id')),
    db.Column('adresse_id', db.Integer, ForeignKey('adresse.id'))
)

 class Restaurants(db.Model):
     __tablename__ = 'restaurants'
   id = db.Column(db.Integer, primary_key=True)
   nom = db.Column(db.String(255))
   description = db.Column(db.String(255))
   creation = db.Column(db.DateTime)
   heure_ouverture = db.Column(db.DateTime)
   heure_fermeture = db.Column(db.DateTime)
   url_photo = db.Column(db.String(255))
   rang = db.Column(db.Integer)
   adresse = db.relationship('Adresse',secondary=restaurant_adresse_association)


 class Adresse(db.Model):
    __tablename__ = 'adresse'
    id = db.Column(db.Integer, primary_key=True)
    ville = db.Column(db.String(255))
    code_postal = db.Column(db.String(255))
    rue = db.Column(db.String(255))
    restaurant = db.relationship('Restaurants', secondary=restaurant_adresse_association)
    longitude = db.Column(db.Float)
    latitude = db.Column(db.Float)

Restaurant.py:

champs_restaurant = {
'id': fields.Integer(attribute='id'),
'name': fields.String(attribute='nom'),
'city': fields.String(attribute='ville'),
'address': fields.String(attribute='rue'),
'postal code': fields.String(attribute='code_postal'),
'description': fields.String,
'opening time': fields.String(attribute='heure_ouverture'),
'closing time': fields.String(attribute='heure_fermeture'),
'picture': fields.String(attribute='url_photo'),
'rank': fields.Integer(attribute='rang')
 }

@marshal_with(champs_restaurant)
def get(self):
    resto = session.query(Restaurants, Adresse).join(Adresse, Restaurants.adresse).all()
    return resto, 201

Результат:

[
[
    {
        "id": 1,
        "name": "Hugiz",
        "city": null,
        "address": null,
        "postal code": null,
        "description": "Fastfood",
        "opening time": "9:00",
        "closing time": "18:00",
        "picture": null,
        "rank": 4
    },
    {
        "id": 1,
        "name": null,
        "city": "Paris",
        "address": "1-3 Rue de Savies",
        "postal code": "75020",
        "description": null,
        "opening time": null,
        "closing time": null,
        "picture": null,
        "rank": 0
    }
],
[
    {
        "id": 2,
        "name": "estampille",
        "city": null,
        "address": null,
        "postal code": null,
        "description": "Pizza",
        "opening time": "9:00",
        "closing time": "18:00",
        "picture": null,
        "rank": 4
    },
    {
        "id": 2,
        "name": null,
        "city": "Rouen",
        "address": "1 Rue Thomas Becket",
        "postal code": "76130",
        "description": null,
        "opening time": null,
        "closing time": null,
        "picture": null,
        "rank": 0
    }
]

тест:

@marshal_with(champs_restaurant)
def get(self):
    resto = session.query(Restaurants).join(Adresse).all()
    return resto, 201

результат:

sqlalchemy.exc.InvalidRequestError: Could not find a FROM clause to join from.  Tried joining to <class 'source.Restaurant.modèle.modele_restaurant.Adresse'>, but got: Can't find any foreign key relationships between 'restaurants' and 'adresse'.

Тест:

@marshal_with(champs_restaurant)
def get(self):
    resto = session.query(Restaurants).join(Adresse, Restaurants.adresse).all()
    return resto, 201

Результат:

[
    {
        "id": 1,
        "name": "Hugiz",
        "city": null,
        "address": null,
        "postal code": null,
        "description": "Fastfood",
        "opening time": "9:00",
        "closing time": "18:00",
        "picture": null,
        "rank": 4
    }, 
    {
        "id": 2,
        "name": "estampille",
        "city": null,
        "address": null,
        "postal code": null,
        "description": "Pizza",
        "opening time": "9:00",
        "closing time": "18:00",
        "picture": null,
        "rank": 4
    }
]

ожидаемый результат:

[
    {
        "id": 1,
        "name": "Hugiz",
        "city": "Paris",
        "address": "1-3 Rue de Savies",
        "postal code": "75020",
        "description": "Fastfood",
        "opening time": "9:00",
        "closing time": "18:00",
        "picture": null,
        "rank": 4
    },
    {
        "id": 2,
        "name": "estampille",
        "city": "Rouen",
        "address": "1 Rue Thomas Becket",
        "postal code": "76130",
        "description": "Pizza",
        "opening time": "9:00",
        "closing time": "18:00",
        "picture": null,
        "rank": 4
    }
]

1 Ответ

0 голосов
/ 14 января 2019

Вы запрашиваете две таблицы с:

session.query(Restaurants, Adresse)

Это в основном эквивалентно SQL-выражению типа

SELECT * FROM restaurants, adresse;

, который создает неявное перекрестное соединение между таблицами, что, вероятно, не то, что вам нужно. Не видя champs_restaurant, трудно точно сказать, что происходит после этого, но, похоже, он пытается объединить результаты, содержащие столбцы из обеих таблиц, в формат JSON, предназначенный для комбинированных результатов.

Часть смысла настройки отношений в SQLAlchemy ORM заключается в том, что вы можете выполнять запросы к таблице, и SQLAlchemy, как правило, создает правильное соединение для вас, предполагая, что отношения внешнего ключа нормальны, поэтому этого должно быть достаточно, если вы хотите перечислить все рестораны, чем заняться:

session.query(Restaurants).all()

Здесь вы получите список Restaurants экземпляров с их атрибутом .adresse, заполненным списком связанных (Adresse экземпляров) через настроенную вами таблицу связей. Он должен использовать ассоциированную таблицу, предоставленную аргументом secondary= для relation, чтобы определить правильные отношения соединения. Если по какой-то причине это все еще не работает, нам придется присмотреться, но в целом это идея.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...