I'm writing a package for Pyramid which has a base AuthUser
declaration. I want to allow users that have installed the package the
ability to extend the AuthUserProfile so that the Mako templates can
be accessed with my subscriber which populates user. with the AuthUser
properties.

Currently, it does not populate ${user.email} where email is declared
in a separate class. I read the documentation and it appeared that
back_populates was probably the option I needed, but, I'm having some
difficulty getting it to work.

In the code, what I'm trying to accomplish is query against AuthUser,
but, have ExtendedProfile's fields available to that query. It seemed
like back_populate should do that, but, it says (correctly) that the
AuthUser doesn't point to a mapper on ExtendedProfile.

In this code sample, what I would like to do is query AuthUser, but,
receive the ExtendedProfile class declarations.

Thanks in advance for any pointer in the right direction.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from sqlalchemy import create_engine
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base

engine = create_engine('mysql://test:test@localhost/test?
use_unicode=1&charset=utf8')
session = sessionmaker(bind=engine, autocommit=True)
DBSession = session()
Base = declarative_base()

import bcrypt
import transaction

from sqlalchemy import Column
from sqlalchemy import ForeignKey
from sqlalchemy import Table
from sqlalchemy import Unicode
from sqlalchemy import types
from sqlalchemy.exc import IntegrityError
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import backref
from sqlalchemy.orm import relation
from sqlalchemy.orm import scoped_session
from sqlalchemy.orm import sessionmaker
from sqlalchemy.orm import synonym
from sqlalchemy.sql import functions

from velruse.store.sqlstore import SQLBase

from zope.sqlalchemy import ZopeTransactionExtension

"""
These definitions are part of a package. I want to have the package
able to query AuthUser, but, to know about the extended attributes.
"""

user_group_table = Table('auth_user_groups', Base.metadata,
    Column('user_id', types.BigInteger(), \
        ForeignKey('auth_users.id', onupdate='CASCADE',
ondelete='CASCADE')),
    Column('group_id', types.BigInteger(), \
        ForeignKey('auth_groups.id', onupdate='CASCADE',
ondelete='CASCADE'))
)

class AuthGroup(Base):
    __tablename__ = 'auth_groups'
    __table_args__ = {"sqlite_autoincrement": True}

    id = Column(types.BigInteger(), primary_key=True)
    name = Column(Unicode(80), unique=True, nullable=False)
    description = Column(Unicode(255), default=u'')

    users = relation('AuthUser', secondary=user_group_table, \
                     backref='auth_groups')

    def __repr__(self):
        return u'%s' % self.name

    def __unicode__(self):
        return self.name


class AuthUser(Base):
    __tablename__ = 'auth_users'
    __table_args__ = {"sqlite_autoincrement": True}

    id = Column(types.BigInteger(), primary_key=True)
    login = Column(Unicode(80), default=u'', index=True)
    username = Column(Unicode(80), default=u'', index=True)
    _password = Column('password', Unicode(80), default=u'',
index=True)
    email = Column(Unicode(80), default=u'', index=True)

    profile = relation('AuthUserProfile', uselist=False,
back_populates='user')

    groups = relation('AuthGroup', secondary=user_group_table, \
                      backref='auth_users')
    """
    Fix this to use association_proxy
    groups = association_proxy('user_group_table', 'authgroup')
    """

    def _set_password(self, password):
        self._password = bcrypt.hashpw(password, bcrypt.gensalt())

    def _get_password(self):
        return self._password

    password = synonym('_password', descriptor=property(_get_password,
\
                       _set_password))

    def in_group(self, group):
        for g in self.groups:
            if g.name == group:
                return True
            else:
                return False

    @classmethod
    def get_by_id(cls, id):
        return DBSession.query(cls).filter(cls.id==id).first()

    @classmethod
    def get_by_login(cls, login):
        return DBSession.query(cls).filter(cls.login==login).first()

    @classmethod
    def get_by_username(cls, username):
        return
DBSession.query(cls).filter(cls.username==username).first()

    @classmethod
    def get_by_email(cls, email):
        return DBSession.query(cls).filter(cls.email==email).first()

    @classmethod
    def check_password(cls, **kwargs):
        if kwargs.has_key('id'):
            user = cls.get_by_id(kwargs['id'])
        if kwargs.has_key('username'):
            user = cls.get_by_username(kwargs['username'])

        if not user:
            return False
        if bcrypt.hashpw(kwargs['password'], user.password) ==
user.password:
            return True
        else:
            return False

class AuthUserProfile(Base):
    __tablename__ = 'auth_user_profile'

    id = Column(types.BigInteger, primary_key=True)
    user_id = Column(types.BigInteger, ForeignKey(AuthUser.id))

    user = relationship('AuthUser', back_populates='profile')

"""
Present in code
"""

class ExtendedProfile(Base):
    __tablename__ = 'auth_user_profile'
    __table_args__ = {'extend_existing':True}
    populate_existing=reload

    id = Column(types.BigInteger, primary_key=True)
    user_id = Column(types.BigInteger, ForeignKey(AuthUser.id))

    email = Column(Unicode(80), unique=True, nullable=False)

    user = relationship('AuthUser', back_populates='profile')


user = DBSession.query(AuthUser).filter(AuthUser.id==1).first()
print 'id:', user.profile.id
print 'email:', user.profile.email

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to