2

私はピラミッドフレームワークでsqlalchemyを使用しており、郵便番号を使用して人を地理部門にリンクしたいと考えています。したがって、department_id列を定義するときにonupdate引数を使用して、department_idを定義しようとします。休閑コードを参照してください:

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]) 

update_atフィールドの更新時に正常に機能しますが、deparment_idフィールドの場合は次のようになります。

NameError:名前'dep_id_from_postcode'が定義されていません

ここでPython実行関数に関するドキュメントを見つけました:http://docs.sqlalchemy.org/en/latest/core/schema.html ?highlight = trigger#python-executed-functions が、onupdateで使用するために別のフィールドを使用するものはありません口論。

私は「自然な英語を話す人」ではないので、十分にはっきりしていることを願っています。ありがとうございました。

4

3 に答える 3

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)
    # ...

postcode本当に直接のフィールドPersonですか? そうでない場合は、これをまったく異なる方法で処理する必要がある可能性があるためです。たとえば、がリレーションシップpostcodeから派生している場合、適切なフックのために、リレーションシップの追加/削除と関連オブジェクトの変更primary_addressを確認する必要があります。primary_addressAddress

于 2012-06-21T10:36:45.277 に答える
5

SQLAlchemy には、デフォルト (つまり onupdate) 関数で他の列値を使用するための特別なメカニズムがあり、次のように呼ばれ ます。 :

デフォルト生成に関するこのコンテキストの典型的な使用例は、行で挿入または更新される他の値にアクセスすることです。

Van が指摘したように、郵便番号が Person に対して定義されたフィールドであることを確認する必要があります。そうしないと、Person インスタンスに関連付けられた郵便番号を取得する機能を追加する必要があります。

私にとってうまくいったのは、オブジェクトにバインドされていない通常の機能です。SQLAlchemy は、挿入および/または更新時にそれを呼び出し、「コンテキスト」を含む特別な引数を渡します。これは、更新している実際のオブジェクトではありません。

あなたの例では、私はこのようなことをします。

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)
    # ...

このコンテキスト引数には注意してください。同じ操作で「郵便番号」値を更新しないと、コンテキストに None フィールドの値がある場合に問題が発生します。

デバッガーを使用した pydev を使用した Eclipse は、コンテキストとして渡される情報を確認するのに役立ちました。

于 2012-06-22T20:27:59.817 に答える