2014-02-02 3 views
2

Имея эту SQLAlchemy модель:ВЫБЕРИТЕ условия на отношениях с SQLAlchemy

class Post(db.Model): 
    __tablename__ = 'posts' 

    post_id = db.Column(db.Integer, primary_key=True) 
    post_parent = db.Column(db.Integer, db.ForeignKey('posts.post_id')) 

    children = db.relationship('Post') 

Как вы можете видеть, Post s может иметь детей (то есть Post сек объекты, post_parent не 0). Для каждого Post, который я извлекаю из базы данных, SELECT выполняется для извлечения его дочерних элементов вместе с ними. Ничего страшного.

Но, в моей базе данных дизайн, Post s, у которого post_parent нет 0, не может быть детей (т. Е. У детей с родительских постов не может быть больше детей под ними). Но SELECT для их получения. Как я могу избежать этого?

+0

что-то вроде: children = db.relationship ('Post', primaryjoin = "and_ (Post.post_id == Post.post_parent, Post.post_parent == 0)"? – Trent

+0

Другая вещь, которую вы можете отметить как lazyload так что, если вы специально не попытаетесь получить доступ к свойству children, он не будет запускать этот дополнительный SQL – Trent

+0

@Trent 'Невозможно определить направление отношений для отношений 'Post.children' - столбцы внешнего ключа в условии соединения присутствуют как в родительском и отображаемые таблицы ребенка. Убедитесь, что только те столбцы, которые относятся к родительскому столбцу, помечены как чуждые, либо через внешнюю() аннотацию, либо через аргумент foreign_keys. ' – monq

ответ

2

В реляционных терминах любое сообщение может иметь дочерние объекты Post, так как все объекты Post имеют первичный ключ, поэтому может быть любое количество объектов Post с этим ключом для post_parent. Поэтому, говоря, что somepost.children должен испускать SQL, иначе SQLA не даст правильных результатов. если ваша модель имеет какое-то специальное правило, некоторые объекты Post, как известно, не имеют дочерних элементов без запроса DB, вам необходимо условно получить доступ к «somepost.children». Однако ваше утверждение о том, что «почтовые объекты, у которых post_parent не равно 0, не может иметь детей», неверно с реляционной точки зрения. Это отношение настроено как «один ко многим», поэтому любой пост может иметь детей, которые не имеют никакого отношения к его post_parent.

Если, с другой стороны, вы действительно имеете в виду, что Post.children является уникальным, много-к-одному для определенной Почты, тогда вам нужно установить remote_side=post_id на это отношение(), и вы не получите lazyload если parent_post в этом случае None (хотя и не ноль, это значение, отличное от NULL).

Смежные вопросы