为啥我的数据没有在我的 SQLAlchemy 模型中正确表示?
Posted
技术标签:
【中文标题】为啥我的数据没有在我的 SQLAlchemy 模型中正确表示?【英文标题】:Why is my data not being represented properly in my SQLAchemy model?为什么我的数据没有在我的 SQLAlchemy 模型中正确表示? 【发布时间】:2010-09-20 14:58:43 【问题描述】:我有一个特殊的 SQLAlchemy ORM 问题。这发生在 Pylons 应用程序中,针对使用 psycopg2 作为我在 SQLAlchemy 0.6.0 下的数据库驱动程序的 Postgresql 8.2 数据库(也尝试使用 0.6.4)
我定义了一个用户模型对象,它(至少)具有以下属性:
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'))
还有其他的,但我认为这些都是密切相关的。
我正在使用此代码在会话中编辑 this 的一个实例(它处理一些其他属性):
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
注意两个 cmets;它们描述了事件的顺序。特别是在提交之前 引发的异常。
我正在做的是将User
的电子邮件字段设置为“user@example.com”并将其设置为“”,这会导致验证器引发异常。在此之后,即使在 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 并通过网络发送,到那时 email 属性是 ''
此查询返回带有电子邮件地址的完整用户(请注意,这都是同一个对象!):
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)
对于这个查询,我得到了正确的用户电子邮件地址。
这里发生了什么,我该如何解决?
【问题讨论】:
你有什么问题?在第一个查询和 JSON 输出之间,电子邮件地址丢失了吗?或者这个特定的地址不应该在那里? 在从数据库返回的查询结果和访问 user.email 属性之间,地址消失了。 【参考方案1】:我不熟悉 pylons,但您的数据库返回似乎没问题(因为电子邮件列不为空)。是否有某种与 pylons 相关的缓存?
【讨论】:
【参考方案2】:这是一个暗中尝试,但请尝试使用 Session.commit()
而不是 self._commit()
。
【讨论】:
以上是关于为啥我的数据没有在我的 SQLAlchemy 模型中正确表示?的主要内容,如果未能解决你的问题,请参考以下文章
如果数据库已经存在,你还需要创建 SQLAlchemy 模型吗?