onupdate基于另一个具有sqlalchemy声明基础的字段

Yoh*_*ann 2 python sqlalchemy pyramid

我使用sqlalchemy和金字塔框架,我想用他的邮政编码将一个人链接到他的地理部门.所以我在定义department_id列定义department_id时尝试使用onupdate参数.看到以下代码:

from datetime import date
from emailing.models import Base, DBSession
from sqlalchemy import Column, Integer, Unicode, Text, DateTime, Sequence, Boolean, Date, UnicodeText, UniqueConstraint, Table, ForeignKey
from sqlalchemy.orm import scoped_session, sessionmaker, column_property, relationship, backref
from sqlalchemy.sql import func

class Person(Base):
    __tablename__ = u'person'
    id = Column(Integer, primary_key=True)

    firstName = Column(Unicode(255))
    lastName = Column(Unicode(255))

    created_at = Column(Date, default=func.now())
    updated_at = Column(Date, onupdate=func.now())

    department_id = Column(Integer(), ForeignKey('department.id'), onupdate=dep_id_from_postcode)
    department = relationship("Department", backref='persons')


    __table_args__ = (UniqueConstraint('firstName', 'lastName'), {})


    def dep_id_from_postcode(self):
        return int(self.postcode[:2]) 
Run Code Online (Sandbox Code Playgroud)

更新的updated_at字段工作正常,但对于deparment_id字段,它告诉我:

NameError:未定义名称'dep_id_from_postcode'

我在这里找到了关于python执行函数的文档:http: //docs.sqlalchemy.org/en/latest/core/schema.html?highlight = strigger#python-executed-functions 但没有使用其他字段在onupdate中使用论点.

我希望我能说清楚,因为我不是"天生的英语演讲者".谢谢大家

van*_*van 7

在使用之前移动函数定义:

class Person(Base):
    # ...
    def dep_id_from_postcode(self):
        return int(self.postcode[:2])
    # ...
    department_id = Column(Integer(), ForeignKey('department.id'), onupdate=dep_id_from_postcode)
    # ...
Run Code Online (Sandbox Code Playgroud)

是postcode真是场直接Person?因为如果不是,您可能需要完全不同地处理这个问题.例如,如果postcode从primary_address关系派生,则需要检查primary_address关系的添加/删除以及相关Address对象中的更改以便正确挂钩.


vvl*_*rov 5

SQLAlchemy具有在默认(即onupdate)函数中使用其他列值的特殊机制:上下文敏感默认函数 http://docs.sqlalchemy.org/en/rel_0_7/core/schema.html#context-sensitive-default-functions:

关于默认生成的此上下文的典型用例是访问在行上插入或更新的其他值.

正如Van指出的那样,您需要确保邮政编码是为Person定义的字段,或者您需要添加将关注获取与Person实例关联的邮政编码的功能.

什么对我有用 - 常规功能,不受任何对象的约束.SQLAlchemy将在插入和/或更新时调用它,并使用"context"传递特殊参数 - 这不是您正在更新的实际对象.

所以对于你的例子,我会做这样的事情.

def dep_id_from_postcode(context):
    postcode = context.current_parameters['postcode']
    return int(postcode[:2])

class Person(Base):
    postcode = Column(String)
    # ...

    # ...
    department_id = Column(Integer(), ForeignKey('department.id'), onupdate=dep_id_from_postcode)
    # ...
Run Code Online (Sandbox Code Playgroud)

小心这个上下文参数 - 如果我没有使用相同的操作更新'postcode'值,在某些情况下上下文具有None字段值时,我最终会遇到问题.

带有调试器的带有pydev的Eclipse帮助我查看了哪些信息作为上下文传递.

  • 当你用一些值来调用`.update`进行更新并且它们不包含''postcode'时,这将不起作用. (3认同)