我有两个表,一个用于参考,另一个用于薪水。我已经在postgres CLI和flask应用程序中成功地将两个表连接在一起,但是尝试在sqlalchemy中查询数据时遇到了问题。
我已经在我的psql CLI上尝试了查询,并且工作正常!
SELECT date, name, profession, wage FROM test2_table JOIN salary ON salary.test2_id = test2_table.id WHERE profession = 'media';
我想我的主要问题是如何在sqlalchemy中做到这一点?
数据库类
class Test_db_02(Base):
__tablename__ = 'test2_table'
id = Column('id', Integer, primary_key=True)
date = Column('date', String(10))
age = Column('age', Integer)
profession = Column('profession', String(60))
city = Column('city', String(60))
country = Column('country', String(60))
def __init__(self, date, name, age, profession, city, country):
self.date = date
self.name = name
self.age = age
self.profession = profession
self.city = city
self.country = country
class Salary(Base):
__tablename__ = 'salary'
id = Column('id', Integer, primary_key=True)
wage = Column('wage', String(20))
test2_id = Column('test2_id', Integer, ForeignKey('test2_table.id')
wages = relationship("Test_db_02", backref="salary", primaryjoin="Test_db_02.id == Salary.test2_id")
我在python中的查询
@app.route('/reports', methods=['GET', 'POST'])
def reports():
if request.method == 'GET':
return render_template('reports.html')
else:
if request.form.get("report_options) == "media_prof":
db_entry = session.query(Test_db_02).join(Test_db_02.salary).filter(Test_db_02.profession=='media')
media_prof = db_entry.all()
return render_template('reports.html', media_prof=media_prof)
report.html中的jinja模板:
{% if media_prof %}
<h2>Media Freelance Reports</h2>
<tr>
<th>ID</th>
<th>NAME</th>
<th>PROFESSION</th>
<th>SALARY</th>
</tr>
{% for d in media_prof %}
<tr>
<th>{{ d.id }}</th>
<th>{{ d.name }}</th>
<th>{{ d.profession }}</th>
<th>{{ d.salary }}</th>
</tr>
{% endfor %}
{% endif %}
幸运的是,它不会使我的Web应用程序崩溃,但没有为每个媒体自由职业者提供薪水,我得到了:
[<__main__.Salary object at 0x00CF11B0>]
我觉得这一定是我在python应用程序中查询数据库的方式,或者是我在Jinja中调用变量的方式。
答案 0 :(得分:1)
由于您是在ORM模式下使用SQLAlchemy(而不是core模式),因此查询的结果
db_entry = session.query(Test_db_02).join(Test_db_02.salary).filter(Test_db_02.profession=='media')
media_prof = db_entry.all()
是Test_db_02实例的列表,每个具有.salary
属性的实例都是Salary
实例。因此,当您在jinja模板中使用它时,这是正常的:
{% for d in media_prof %}
<tr>
<th>{{ d.id }}</th>
<th>{{ d.name }}</th>
<th>{{ d.profession }}</th>
<th>{{ d.salary }}</th>
</tr>
{% endfor %}
由于d.salary
是Salary
实例的实际列表(由于您的backref和您之间存在一对多的关系),这意味着您可以访问的属性每个薪水对象,例如:.id
或.wage
例如:
{% for d in media_prof %}
<tr>
<th>{{ d.id }}</th>
<th>{{ d.name }}</th>
<th>{{ d.profession }}</th>
{% for s in media_prof.salary %}
<th>{{ s.id }}</th>
<th>{{ s.wage }}</th>
{% endfor %}
</tr>
{% endfor %}
注意:考虑将您的backref“薪水”重命名为“薪水”,以使其更加明确
编辑: 请注意,对模板外部的内容进行故障排除更容易。从终端,我可以使用以下简化的情况获得正确的输出:
# Load an object in the db with 2 salaries attached to it
t = Test_db_02(city='NY')
s1 = Salary(wage='crazy rich', test2_id=t)
s2 = Salary(wage='mega rich', test2_id=t)
t.salaries = [s1, s2]
session = Session()
session.add(t)
session.commit()
# query & print
session2 = Session()
for test in session2.query(Test_db_02).all():
print(test.id, test.city)
for salary in test.salaries:
print(salary.id, salary.wage)
可打印
1 NY
1 crazy rich
2 mega rich