2017-01-10 8 views
1

Как я могу запросить только определенные столбцы таблицы И возвращать поля с отношениями «один ко многим» в виде списков в flask-sqlalchemy?Flask-SQLAlchemy: запрашивать только определенные столбцы, возвращать отношения «один ко многим» как списки

Это мой models.py:

class Article(db.Model): 
    __tablename__ = 'articles' 

    id = db.Column(db.Integer, primary_key=True) 
    title = db.Column(db.String(255)) 
    full_text = db.Column(db.Text) 
    authors = relationship('Person', 
      secondary=AssArtPer, 
      backref='articles' 
      ) 

class Person(db.Model): 
    __tablename__ = 'persons' 
    id = db.Column(db.Integer, primary_key=True) 
    full_name = db.Column(db.String(255)) 


AssArtPer = db.Table('ass_articles_persons', 
    db.Column('art_id', db.Integer, db.ForeignKey('articles.id')), 
    db.Column('per_id', db.Integer, db.ForeignKey('persons.id')) 
    ) 

Когда я

results = Article.query.all() 

EDIT: Я после прохождения results в шаблон jinja2 который передать ее в макрос:

{% for r in results %} 
    {% macros.render_article(r) %} 
{% endfor %} 

{% macro render_article(result) %} 
    {% for a in result.authors %} 
     ...render something 
    {% endfor %} 
{% endmacro %} 

Теперь я хотел бы ограничить исходный запрос, чтобы исключить Article.full_te xt, потому что он занимает очень много времени, и я могу позже загрузить полный текст с помощью ajax-вызова. Я знаю, что я могу указать определенные столбцы для запроса:

results = Article.query.with_entities(
    Article.id, 
    Article.title, 
    Article.authors 
    ).all() 

НО это не работает. Запрос ничего не возвращает и не вызывает ошибок.

Я попробовал присоединиться как так:

results = Article.query.join(Article.authors).with_entities(Person.id, Person.full_name) 

... который работает нормально, но я не могу указать любые другие столбцы тогда.

Как объединить два запроса?

+0

В вашем последнем примере вы присоединяетесь 'статью '' '' Статьи'. Это намеренно? – ACV

+0

Я думаю, что есть некоторые проблемы с вашим вопросом. Во-первых, я не могу воспроизвести поведение, которое вы получаете с помощью 'results = Article.query.all()' и 'для имени в results.authors:' - В этом случае 'results' - список объектов; примеры вашего класса Article. 'results.authors' не должно даже работать. Если вы берете один объект из этого результирующего набора, этот объект будет иметь атрибут 'author', который, вероятно, будет списком по умолчанию. Я думаю, что вы хотите сделать, это определить ленивый backref, так что '.authors' возвращает запрос, который вы можете фильтровать вместо объединенного списка результатов. – sytech

+0

@sytech: Верно, ради краткости я был недостаточно ясен. Я фактически передаю «результаты» шаблону jinja2, который затем передает его макросу внутри цикла for. В макросе я затем печатаю 'results.authors' один за другим. Я отредактирую вопрос соответствующим образом. – synul

ответ

0

на основе this question я думаю, что следующий может работать:

results = (
    Article.query.join(Person). 
    with_entities([ 
     Article.id, 
     Article.title, 
     Article.authors, 
     Person.id, 
     Person.full_name]).all() 

(Дайте мне знать, если это не так, у меня есть еще одна идея.)

+0

К сожалению, это не работает. Я получаю выражение InvalidRequestError: SQL, столбец или сопоставленный объект - получил [', ...'] ' – synul

+0

вы сказали, что у вас есть другая идея? – synul

+0

Да, я доберусь до этого в эти выходные! – ACV