выпуск события sqlalchemy mapper - PullRequest
       8

выпуск события sqlalchemy mapper

0 голосов
/ 06 декабря 2011

Я определил следующие классы в sqlalchemy:

class User(Base):
    __tablename__ = 'user'
    userId = Column(Integer, primary_key=True)
    email = Column(String(60), unique=True,nullable=False)
    userName = Column(Unicode(16),unique=True)
    _password = Column('password', Unicode(60))
    groups = relationship("Group",secondary='userGroup') 
    profile = relationship("UserProfile",uselist=False,backref='user') 

class Group(Base):
        __tablename__ = 'group'
        groupId = Column(Integer,
                       Sequence('group_id_seq', optional=True),
                       primary_key=True)
        groupName = Column(Unicode(255), unique=True)

UserGroupTable = Table('userGroup', Base.metadata,
        Column('userId', Integer, ForeignKey(User.userId)),
        Column('groupId', Integer, ForeignKey(Group.groupId))
    )


class UserProfile(Base):
    __tablename__='userProfile'
    userId = Column(Integer, ForeignKey('user.userId'), primary_key=True)
    dateJoin = Column(Date,nullable=False,default=func.current_date())
    gender = Column(Integer)

user имеет отношение многие ко многим с group, и когда я инициализировал таблицы, я добавил две группы 'user' и 'admin', как показано ниже. Проблема в том, что когда я использую событие mapper для добавления пользователя в группу 'user' при вставке, оно не работает:

def before_insert_user_listener(mapper,connection,target):
    session=DBSession()
    ug=session.query(Group).filter(Group.groupName=='user').first()
    target.groups.append(ug)    
    target.profile=UserProfile()
    log.debug(">>>>>")

def initialize_sql(engine):
    DBSession.configure(bind=engine)
    Base.metadata.bind = engine
    Base.metadata.create_all(engine)
    try:
        session = DBSession()
        #event register
        event.listen(User,'before_insert',before_insert_user_listener)
        group1 = Group('admin')
        group2 = Group('user') 
        session.add(group1)
        session.add(group2)           
        transaction.commit()
    except IntegrityError:
        pass

Когда я пытаюсь добавить нового пользователя, он добавляется, и я вижу распечатку журнала из прослушивателя событий, но пользователь не добавляется в группу 'user'. Я также попробовал событие after_insert, но оно также не сработало.

Редактировать: я добавляю таблицу userProfile, которая является отношением «один к одному» с пользователем, и можно создать профиль пользователя с датой соединения по умолчанию в указанном выше событии before_insert хотя добавить пользователя в группу все еще не работает.

Что я пропустил?

Спасибо!

1 Ответ

1 голос
/ 07 декабря 2011

Как следует из выдержки из документации before_insert :

Атрибуты на основе столбцов могут быть изменены в этом методе, что приведет к вставке нового значения.Однако никаких изменений в общий план сброса сделать нельзя, и манипулирование сеансом не даст желаемого эффекта.Чтобы манипулировать сессией внутри расширения, используйте SessionExtension.

, из которого я заключаю, что нельзя добавлять новые объекты в сеанс, который фиксируется / сбрасывается, или добавлять / устанавливать отношения.

Полагаю, лучшим способом было бы прослушать before_commit или before_flush событие сеанса, проверить все новые объекты User и добавить их в группу User.Например:

def my_before_commit(session):
    g=session.query(Group).filter(Group.groupName=='user').one()
    for target in session:
        if isinstance(target, User) and target in session.new:
            target.groups.append(ug)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...