Comments 17
Post.query.join(followers, (followers.c.followed_id == Post.user_id)).filter(followers.c.follower_id == self.id).order_by(Post.timestamp.desc())»
Ммм как же я люблю ORM…
SELECT *
FROM posts
WHERE author IN
(SELECT followed FROM followers WHERE follower=?)
ORDER BY timestamp
test_follow_posts
не проходит.UPD Всё проходит.
Привет!
Что-то не пойму, как это работает:
if user == current_user:
Эти объекты разные, если смотреть функцией id(), получается сравнение идет по атрибутам класса. Где это реализовано, в каком классе?
Всё. Нашел случайно )) Реализовано в миксин-классе UserMixin:
class UserMixin(object):
...
def __eq__(self, other):
...
...
Может кто подскажет, как в Python увидеть, в каком родительском классе реализуется конкретный метод? Не просто класс который реализует метод, так как метод теоретически может реализовываться в каждом из них, а тот, который действует на конечный результат?
Например, в этом примере ясно, что переопределяется в UserMixin, а если бы метод _eq_ реализовывался где нибудь в недрах API flask-sqlalchimy или в самой sqlalchimy, как это найти, есть ли какие инструменты?
Содержит кортеж с родительскими типами, выстроенными в порядке разрешения методов.
Свойство доступно только для чтения.
Порядок разрешения методов (Method Resolution Order — MRO), рассчитанный при помощи алгоритма C3 представляет собой линеаризацию (построение линейного вида) иерархии классов. Алгоритм позволяет разрешить возможные конфликтные ситуации при множественном наследовании (конфликт методов, проблема ромба).
Два (из трех — C3) основных правила линеаризации:
1. дети идут раньше родителей;
2. родители идут в порядке перечисления.
list.__mro__ # (list, object)
class A(object): pass
class B(A): pass
class C(A): pass
class BC(B, C): pass
BC.__mro__
# (__main__.BC, __main__.B, __main__.C, __main__.A, object)
дальше иди по классам справа налево и ищи в них метод который тебя интересует. Последний найденный и будет использоваться твоим экземпляром.
Функция super() Доклад с PyCon US 2015 — ежегодной конференции python-разработчиков. Докладчик: Реймонд Хеттинджер. переведено на русский
И еще такой вопрос, а как получается, что таблица (или переменная) followers объявленная вне класса, над классом User доступна из объекта класса?
Пример:
файл /app/models.py:
...
followers = db.Table('followers',
db.Column('follower_id', db.Integer, db.ForeignKey('user.id')),
db.Column('followed_id', db.Integer, db.ForeignKey('user.id'))
)
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), index=True, unique=True)
email = db.Column(db.String(120), index=True, unique=True)
password_hash = db.Column(db.String(128))
...
Затем это как-то доступно в шаблоне — user.followers.count():
...
<p>
{{ user.followers.count() }} followers, {{ user.followed.count() }} following.
</p>
...
и при этом не понятно, как работает count() в конструкции user.followers.count(), если вне класса обявлена только таблица и её колонки? Что-то вообще всё не явно.
К этой статье указаны одни из следующих тегов: flowers, flowed
Это шутка такая, намеренно сделано? Или это опечатка и вместо последователей внесены цветочки и течь? ))
Какой ужас этот ORM.
Вместо простого запроса "SELECT COUNT(*) FROM folowers WHERE folower_id=? AND folowed_id=? LIMIT 1;" такой трэш и угар. Судя по всему в предложенной версии зачем-то сначала составляется список всех подписанных пользователей, и потом по нему прогоняется отдельный запрос для нужного юзера.
Да и в поиске постов можно было прекрасно обойтись без union. Сдаётся мне, что с таким конструированием запросов не только падает наглядность, но и растёт время их выполнения.
....Хороший ORM – отсутствующий ORM.... :) Это не моё. Это здесь https://habr.com/ru/post/458286/
И ещё:...Как правило, «низкоуровневый» API базы данных прост, удобен, полон и консистентен....
Так что, есть и такие точки зрения. Всё зависит от привычек и "нравится/не нравится".
В комментариях статьи, на которую я привёл ссылку, есть доводы в защиту ORM. Там много интересного. А здесь просто перевод главы из публикации Мигеля Гринберга.
Мега-Учебник Flask, Глава 8: Подписчики, контакты и друзья (издание 2018)