Skip to main content
 首页 » 编程设计

python之为什么我的数据没有在我的 SQLAlchemy 模型中正确表示

2025年05月04日9mayingbao

我有一个特殊的 SQLAlchemy ORM 问题。这发生在 Pylons 应用程序中,针对使用 psycopg2 作为我在 SQLAlchemy 0.6.0 下的数据库驱动程序的 Postgresql 8.2 数据库(也尝试使用 0.6.4)

我定义了一个 User 模型对象,它(至少)具有以下属性:

class User(Base): 
    __tablename__ = 'users' 
 
    __table_args__ = (saschema.UniqueConstraint("login", "company_id"), {}) 
 
    __mapper_args__ = { 
      'order_by' : 'lower(users.name)', 
      } 
 
    user_id = Column(Integer, primary_key=True) 
    email = Column(String) 
    login = Column(String) 
    company_id = Column(String, ForeignKey('company.company_id')) 

还有其他的,但我认为这些都是密切相关的。

我正在使用这段代码在 session 中编辑它的一个实例(它处理其他一些属性):

def do_update(user_id): 
    existing = Session().query(User).filter_by(user_id=user_id).one() 
 
    for field in ('login', 'email', 'name', 'is_admin_user'): # only email changes; it's set to "" from "foo@bar.com" 
        if field in params: 
            setattr(existing, field, params[field]) 
 
    if 'advanis_portal_user_id' in params: 
        if not existing.portal_link: 
            existing.portal_link = UserPortalLink() 
        existing.portal_link.advanis_portal_user_id = params['advanis_portal_user_id'] 
 
    if 'password' in params and existing.password: 
        existing.password.password = Password.encrypt(existing.login, params['password']) 
 
    UserValidator(existing) # raises an exception 
    self._commit() 
    return existing 

注意两条评论;他们描述了事件的顺序。特别是提交之前引发的异常。

我正在做的是将电子邮件字段设置为“user@example.com”的 User 设置为“”,这会导致验证器引发异常。此后,即使在 Pylons 服务器重新启动后,通过以下查询返回的用户也有 '' 的电子邮件地址!这两个查询返回具有“”电子邮件地址的用户:

Session().query(User).filter_by(login=login, company_id=company).one() 
Session().query(User).all() 

这是这两个查询中第一个查询的 SQL/参数/响应:

[sqlalchemy.engine.base.Engine] BEGIN 
[sqlalchemy.engine.base.Engine] SELECT users.user_id AS users_user_id, users.login AS users_login, users.name AS users_name, users.email AS users_email, users.company_id AS users_company_id, users.is_admin_user AS users_is_admin_user  
FROM users  
WHERE %(param_1)s = users.company_id ORDER BY lower(users.name) 
[sqlalchemy.engine.base.Engine] {'param_1': u'offby1'} 
[sqlalchemy.engine.base.Engine] Col ('users_user_id', 'users_login', 'users_name', 'users_email', 'users_company_id', 'users_is_admin_user') 
[sqlalchemy.engine.base.Engine] Row (8, u'newuser', u'A new user', u'chris.rose@advanis.ca', u'offby1', False) 
[sqlalchemy.engine.base.Engine] Row (3, u'crose', u'Chris Rose', u'chris.rose@advanis.ca', u'offby1', True) 

请注意,电子邮件地址已返回。该对象被编码为 JSON 并通过网络发送,此时电子邮件属性为 ''

此查询返回具有电子邮件地址的完整用户(请注意,这是同一个对象!):

Session().query(User).filter_by(user_id=user_id).one() 

这是该查询的详细日志记录:

[sqlalchemy.engine.base.Engine] BEGIN 
[sqlalchemy.engine.base.Engine] SELECT users.user_id AS users_user_id, users.login AS users_login, users.name AS users_name, users.email AS users_email, users.company_id AS users_company_id, users.is_admin_user AS users_is_admin_user  
FROM users  
WHERE users.user_id = %(user_id_1)s ORDER BY lower(users.name) 
[sqlalchemy.engine.base.Engine] {'user_id_1': u'3'} 
[sqlalchemy.engine.base.Engine] Col ('users_user_id', 'users_login', 'users_name', 'users_email', 'users_company_id', 'users_is_admin_user') 
[sqlalchemy.engine.base.Engine] Row (3, u'crose', u'Chris Rose', u'chris.rose@advanis.ca', u'offby1', True) 

对于这个查询,我得到了正确的用户电子邮件地址。

这里发生了什么,我该如何解决?

请您参考如下方法:

我不熟悉 Pylons ,但您的数据库返回似乎没问题(因为电子邮件列不为空)。 Pylons 有某种缓存吗?