GeraJet
@GeraJet
Anykey

Как правильно составить join-запрос в приложении на Flask?

Модели:
class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100))
    username = db.Column(db.String(120), unique=True)
    password = db.Column(db.String(120))

    def __init__(self, name, username, password):
        self.name = name
        self.username = username
        self.password = password

class Weather(db.Model):
    __tablename__ = 'weather'
    id = db.Column(db.Integer, primary_key=True)
    ray_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    ray = db.relationship('User', backref=db.backref('weather_current', uselist=False))   
    putdate = db.Column(db.DateTime)
    sost = db.Column(db.String(250))
    temp = db.Column(db.String(150))

    def __init__(self, ray_id, putdate, sost, temp):
        self.ray_id = ray_id
        self.putdate = putdate
        self.sost = sost
        self.temp = temp


Вьюшка:
@mod.route('/', methods = ['GET', 'POST'])
def weather():
    rows = Weather.query.outerjoin(User, Weather.ray_id==User.id).order_by(User.name.asc())
    return render_template("weather/weather.html",
        rows = rows)


Шаблон:
{% for row in rows %}
	<tr>
	<td align=left>{{ row.name }}</td>
	<td>{{ row.putdate }}</td>
	<td>{{ row.sost }}</td>
	<td>{{ row.temp }}</td>
	</tr>
 {% endfor %}


Выводятся данные только по модели Weather, как вывести данные пользователя, например, {{ row.username }}

Запрос во views соответствует sql-запросу
SELECT * FROM weather LEFT JOIN users ON weather.id_ray = users.id ORDER BY users.name asc"

На PHP все прекрасно работает.
  • Вопрос задан
  • 4233 просмотра
Решения вопроса 1
@sormon
инженер-программист =)
{{ row.ray.username }}
И вместо
rows = Weather.query.outerjoin(User, Weather.ray_id==User.id).order_by(User.name.asc())

Можно просто написать
rows = Weather.query.outerjoin(User).order_by(User.name.asc())


Полный пример:
from flask import Flask, render_template
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///tst.db'
db = SQLAlchemy(app)

import datetime

class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100))
    username = db.Column(db.String(120), unique=True)
    password = db.Column(db.String(120))

    def __init__(self, name, username, password):
        self.name = name
        self.username = username
        self.password = password

class Weather(db.Model):
    __tablename__ = 'weather'
    id = db.Column(db.Integer, primary_key=True)
    ray_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    ray = db.relationship('User', backref=db.backref('weather_current', uselist=False))   
    putdate = db.Column(db.DateTime)
    sost = db.Column(db.String(250))
    temp = db.Column(db.String(150))

    def __init__(self, ray_id, putdate, sost, temp):
        self.ray_id = ray_id
        self.putdate = putdate
        self.sost = sost
        self.temp = temp
db.drop_all()
db.create_all()

u = User("usertest2", 'testuser2', '123')

db.session.add(u)
db.session.commit()
db.session.add(Weather(u.id, datetime.datetime.now(), 'test', '123'))
db.session.add(Weather(None, datetime.datetime.now(), 'test', '123'))
db.session.commit()
        
@app.route('/', methods = ['GET', 'POST'])
def weather():
    rows = Weather.query.outerjoin(User).order_by(User.name.asc())
    return render_template("weather.html",
        rows = rows)
if __name__ == "__main__":
    app.run(debug=True)


Шаблон:
<table>
{% for row in rows %}
  <tr>
  <td align=left>{{ row.ray.name }}</td>
  <td>{{ row.putdate }}</td>
  <td>{{ row.sost }}</td>
  <td>{{ row.temp }}</td>
  <td>{{ row.ray.username }}</td>
  </tr>
 {% endfor %}
</table>
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@Archet
Я бы предложил обратить внимание на add_entity, но я не уверен в том, насколько это решение правильное, ибо сам во фласке только разбираюсь.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы