Created
November 20, 2014 22:43
-
-
Save singingwolfboy/7362f19ebb980bb29922 to your computer and use it in GitHub Desktop.
I'm trying to set a relationship between User and UserEmail so that when I reference user.emails, the first email in the list is always the primary email. However, I'm getting `ProgrammingError: missing FROM-clause entry for table "app_user"` when I try to reference User.emails. How can I make this work? I might be going about this all wrong...
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# coding=utf-8 | |
from __future__ import unicode_literals, division | |
import sqlalchemy as sa | |
from sqlalchemy.orm import relationship, backref | |
from sqlalchemy.ext.declarative import declarative_base | |
from sqlalchemy.ext.hybrid import hybrid_property | |
from werkzeug.security import generate_password_hash, check_password_hash | |
Base = declarative_base() | |
class User(Base): | |
__tablename__ = "app_user" | |
id = sa.Column(sa.Integer, primary_key=True) | |
username = sa.Column(sa.String(255), unique=True, nullable=False) | |
password_hash = sa.Column(sa.String(255)) | |
primary_email = sa.Column(sa.String(255)) | |
@hybrid_property | |
def email(self): | |
""" | |
This is the object associated with the primary email. | |
""" | |
pes = [e for e in self.emails if self.primary_email == e.email] | |
if len(pes) < 1: | |
raise ValueError("missing primary email for user {}".format(self)) | |
if len(pes) > 1: | |
raise ValueError("multiple primary emails for user {}".format(self)) | |
return pes[0] | |
@email.expression | |
def email(cls): | |
return ( | |
UserEmail.query | |
.join(cls) | |
.where(cls.primary_email == UserEmail.email) | |
) | |
@property | |
def password(self): | |
raise AttributeError('password is not a readable attribute') | |
@password.setter | |
def password(self, password): | |
self.password_hash = generate_password_hash(password) | |
def verify_password(self, password): | |
return check_password_hash(self.password_hash, password) | |
def __unicode__(self): | |
return self.username | |
class UserEmail(Base): | |
__tablename__ = "app_user_email" | |
id = sa.Column(sa.Integer, primary_key=True) | |
email = sa.Column(sa.String(255), nullable=False, unique=True) | |
user_id = sa.Column(sa.Integer, sa.ForeignKey(User.id)) | |
user = relationship(User, backref=backref( | |
"emails", | |
order_by=(User.primary_email == email), | |
)) | |
@property | |
def primary(self): | |
return self.user.primary_email == self.email | |
def __unicode__(self): | |
return self.email |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment