我使用最好的SQLAlchemy查询吗?

时间:2016-05-19 03:50:19

标签: python sqlite sqlalchemy flask-sqlalchemy

我有一个Opportunity表和一个Owner表。 Opportunity表与Owner具有多对一关系。我在这个项目上使用Python,SQLAlchemy,FLask-Alchemy和SQLite。我需要针对Owner表在Opportunity表上进行内部联接并返回单个结果集(包含两个表中的字段)。

我需要在结果集中构建一个字典,以便我可以轻松生成Json。下面的代码都可以工作......但是...需要大量的调试才能弄清楚如何将返回的结果集(在本例中是生成器对象)转换为字典。

我是否比我需要的更难?使用SQLAlchemy有更好的方法吗? (例如使用表达式语言而不是ORM)

owner = db.session.query(Owner).filter(Owner.id == owner_id).first()
if owner is None:
    return None

result = {'data': []}
report_date = datetime.datetime.strptime('2016-05-01', '%Y-%m-%d')

rows = db.session.query(Opportunity)\
                 .filter(Opportunity.status == 'Won',
                         Opportunity.owner == owner,
                         or_(Opportunity.actual_close_date_iso_year_week == '2016/16',\
                             Opportunity.actual_close_date_iso_year_week == '2016/17'),
                         Opportunity.report_date == report_date)\
                 .order_by(Opportunity.account)\
                 .join(Owner, Owner.id == Opportunity.owner_id)\
                 .values(Opportunity.account,
                         Opportunity.report_date_iso_year_week,
                         Opportunity.report_date,
                         Owner.first_name)

for row in rows:
    result_row = {}
    fields = getattr(row, '_fields')
    for field in fields:
        result_row[field] = getattr(row, field)
    result['data'].append(result_row)

1 个答案:

答案 0 :(得分:1)

我认为基本上这是获得所需内容的方式,但我建议稍作修改:

  • 您真的不需要加入,因为在.filter(Opportunity.owner==owner)之后,您从Opportunity表中获得的所有行都具有相同的owner_id

  • 我认为最好定义一次所需字段列表,而不是尝试从每个行元组中获取它。

所以,代码可能是这样的:

required_fields = ('account','report_date_iso_year_week','report_date')
owner = db.session.query(Owner).filter(Owner.id == owner_id).first()
if owner is None:
    return None

result = {'data': []}
report_date = datetime.datetime.strptime('2016-05-01', '%Y-%m-%d')

rows = db.session.query(Opportunity)\
                 .filter(Opportunity.status == 'Won',
                         Opportunity.owner == owner,
                         or_(Opportunity.actual_close_date_iso_year_week == '2016/16',\
                             Opportunity.actual_close_date_iso_year_week == '2016/17'),
                         Opportunity.report_date == report_date)\
                 .order_by(Opportunity.account)\
                 .values(*[getattr(Opportunity,f) for f in required_fields])

for row in rows:
    result_row = {'first_name':owner.first_name}
    for field in required_fields:
        result_row[field] = getattr(row, field)
    result['data'].append(result_row)