Уведомления

Группа в Telegram: @pythonsu

#1 Июль 20, 2014 07:19:13

lightarhont
Зарегистрирован: 2014-07-20
Сообщения: 44
Репутация: +  1  -
Профиль   Отправить e-mail  

Pyramid+SQLAlhemy не могу разобраться с транзакциями

Делаю коммит и получаю призраки бывших данных.
Т.е. информация в базе данных меняется и всё вроде бы хорошо, но при обновлении таблицы всплывают старые данные. Помогите! А то я никак не могу въехать как это возможно при полной перезагрузки страницы.

from sqlalchemy import (
    Column,
    Index,
    Integer,
    Text,
    String,
    Unicode,
    ForeignKey,
    Table,
    Date,
    )
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.orm import (
    scoped_session,
    sessionmaker,
    backref,
    relationship,
    )
from zope.sqlalchemy import ZopeTransactionExtension
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
Base = declarative_base()
class Users(Base):
    __tablename__ = 'users'
    __table_args__ = {'mysql_engine':'InnoDB'}
    
    id = Column(Integer, primary_key=True)
    username = Column(Unicode(32), unique=True)
    email    = Column(Unicode(32), unique=True)
    password = Column(Unicode(64))
    blocked = Column(Integer)
    
    roles = association_proxy('roles_users', 'roles')
    
    profiles = relationship("Profiles", uselist=False)
    
    def __init__(self, username, email, password, blocked, roles=None):
        self.username = username
        self.password = password
        self.email    = email
        self.blocked  = blocked
        if roles:
            self.roles  = roles
        
    def check_password(self, passwd):
        return self.password == passwd
def get_user(username):
    user = DBSession.query(Users).filter(Users.username == username).all()
    if user:
        return user[0]
    else:
        return None
    
class Roles(Base):
    __tablename__ = 'roles'
    __table_args__ = {'mysql_engine':'InnoDB'}
    
    id          = Column(Integer, primary_key=True)
    name        = Column(Unicode(32))
    rolesgroup  = Column(Unicode(32))
    description = Column(Unicode(255))
    
    users = association_proxy('roles_users', 'users')
    
    def __init__(self, name):
        self.name = name
        #self.description = description
        
class RolesUsers(Base):
    __tablename__ = 'roles_users'
    __table_args__ = {'mysql_engine':'InnoDB'}
    
    user_id = Column(Integer, ForeignKey('users.id'), primary_key=True)
    role_id = Column(Integer, ForeignKey('roles.id'), primary_key=True)
    
    users = relationship('Users', backref=backref("roles_users"))
    roles = relationship('Roles', backref=backref("roles_users"))
    
    def __init__(self, user_id, role_id):
        self.user_id = user_id
        self.role_id = role_id
class Profiles(Base):
    __tablename__ = 'profiles'
    __table_args__ = {'mysql_engine':'InnoDB', 'mysql_collate': 'utf8_general_ci'}
    
    id        = Column(Integer, primary_key=True)
    userid    = Column(Integer, ForeignKey('users.id'))
    fullname  = Column(Unicode(64))
    register  = Column(Date)
    lastlogin = Column(Date)
    expired   = Column(Date)
    
    def __init__(self, fullname, register, lastlogin, expired):
        self.fullname  = fullname
        self.register  = register
        self.lastlogin = lastlogin
        self.expired   = expired
    

from pyramid.view import view_config, view_defaults
from .common import *
from sqlalchemy import desc, asc
import transaction
from testproject.models.users import (
    Users,
    Roles,
    RolesUsers,
    DBSession,
    )
import json
@view_config(route_name='managerparam4', xhr=True, renderer='string', match_param=('p1=options', 'p2=control', 'p3=users', 'p4=updateitem'))
def updateitem(request):
    post = request.POST.mixed()
    roles = json.loads(post['roles'])
    #Добавляем запись
    obj = DBSession.query(Users).filter(Users.id == post['id']).one()
    obj.username = post['username']
    obj.email    = post['email']
    obj.profiles.fullname = post['fullname']
    if post['password'] != '':
        obj.password = post['password']
    obj.blocked  = 0
    DBSession.add(obj)
    #transaction.commit()
    
    #Удаляем роли
    DBSession.query(RolesUsers).filter(RolesUsers.user_id == post['id']).delete()
    #transaction.commit()
    
    #Добавляем роли
    for e in roles:
        ru = RolesUsers(post['id'], e)
        DBSession.add(ru)
    DBSession.flush()
    transaction.commit()
    
    result = 'this'
    return result

Офлайн

#2 Июль 20, 2014 11:33:18

bismigalis
Зарегистрирован: 2010-10-02
Сообщения: 449
Репутация: +  47  -
Профиль   Отправить e-mail  

Pyramid+SQLAlhemy не могу разобраться с транзакциями

не вижу ничего криминального, должно работать

Т.е. информация в базе данных меняется и всё вроде бы хорошо,
значит транзакция отрабатывает
но при обновлении таблицы всплывают старые данные.
что за обновление

несколько советов:
DBSession.add(obj)
делать не нужно, obj уже в сессии после загрузки. add нужно делать для вновь созданных объектов

DBSession.flush()
делать нужно редко, вызывается перед commit() автоматически. Руками нужно вызывать только если нужно получить данные с сервера, например добавил в сессию объект с автоинкрементным полем и нужно получить это значение до коммита.

transaction.commit()
делать нужно редко, вызывается автоматически мидлварью pyramid_tm, если небыло выброшено исключение

Офлайн

#3 Июль 20, 2014 11:44:26

lightarhont
Зарегистрирован: 2014-07-20
Сообщения: 44
Репутация: +  1  -
Профиль   Отправить e-mail  

Pyramid+SQLAlhemy не могу разобраться с транзакциями

bismigalis
не вижу ничего криминального, должно работать
Дак работает! Просто старые данные берёт откуда то, хотя в базе уже новые данные! При загрузке. Причём ещё в перемешку с новыми, т.е. один раз обновил страницу - Новые данные. Другой раз - Старые данные!
Я как долгий PHP-ник не могу вкурить почему так…
Как очистить кеш или DBSession?

Офлайн

#4 Июль 20, 2014 12:07:57

lightarhont
Зарегистрирован: 2014-07-20
Сообщения: 44
Репутация: +  1  -
Профиль   Отправить e-mail  

Pyramid+SQLAlhemy не могу разобраться с транзакциями

У меня где-то вот такая же ошибка:
http://stackoverflow.com/questions/12837527/sqlalchemy-pyramid-dbsession-refresh-issue

Офлайн

#5 Июль 20, 2014 14:12:28

lightarhont
Зарегистрирован: 2014-07-20
Сообщения: 44
Репутация: +  1  -
Профиль   Отправить e-mail  

Pyramid+SQLAlhemy не могу разобраться с транзакциями

Всё вроде… Баг был на уровне mysql как не странно, поскольку в PHP проблем с чтеним новых данных не возникало…
Добавил в my.cnf


binlog_format=mixed
transaction-isolation = READ-UNCOMMITTED

Офлайн

#6 Июль 21, 2014 05:06:21

PooH
От:
Зарегистрирован: 2006-12-05
Сообщения: 1948
Репутация: +  72  -
Профиль   Отправить e-mail  

Pyramid+SQLAlhemy не могу разобраться с транзакциями

lightarhont
transaction-isolation = READ-UNCOMMITTED
Безумству храбрых поем мы песни



Вот здесь один из первых отарков съел лаборанта. Это был такой умный отарк, что понимал даже теорию относительности. Он разговаривал с лаборантом, а потом бросился на него и загрыз…

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version