我有一个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)
答案 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)