4

sqlalchemy の inspect 関数を使用して、特定のモデルの履歴を通常の値で見つけることができます。ただし、リレーションシップ (または関連する ForeignKey 列) の履歴を取得しようとすると、以前の値ではなく、新しい値のみが表示されます。

このような関係の以前の値を取得する簡単な方法はありますか、それとも別の関数を使用する必要がありますか?

私が使用している基本的なコードは次のようになります

class Person(db.Model):
  id = db.Column(db.Integer(), primary_key=True)
  name = db.Column(db.String(80))
  phone_id = db.Column(db.Integer(), db.ForeignKey("phone_number.id"))
  phone = db.relationship("PhoneNumber")
class PhoneNumber(db.Model):
  id = db.Column(db.Integer(), primary_key = True)
  type = db.Column(db.String(20))
  number = db.Column(db.String(11))

p = Person()
p.name = "Frank"
phone1 = PhoneNumber("Mobile", "1234567890") #__init__ function handles these args
phone2 = PhoneNumber("Home", "9876543210")
p.phone = phone1
db.session.add_all([p, phone1, phone2])
db.session.commit()
p.phone = phone2
history = db.inspect(p).attrs.get("phone").history
# history is sqlalchemy.orm.attributes.History(([<PhoneNumber('Home', '9876543210')>], (), ()))
# history.added is ([<PhoneNumber('Home', '9876543210')>])
# history.deleted is () but should be ([<PhoneNumber('Mobile', '1234567890')>])
4

1 に答える 1

4

スカラー属性の「古い」値は、通常、まだ存在しない場合はデータベースからロードされません。これは通常、無駄になるためです (この場合、session.commit() はすべての属性を期限切れにするため、新しい値が読み込まれると Person.phone はアンロードされます)。割り当てられています)。例外には、列が主キー列である場合、または単純な多対 1 以外のものとのスカラー関係の場合が含まれます。この「古い」値のロードは、問題の属性で「active_history」オプションを使用することによって強制できます。

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Person(Base):
    __tablename__ = 'person'
    id = Column(Integer(), primary_key=True)
    name = Column(String(80))
    phone_id = Column(Integer(), ForeignKey("phone_number.id"))
    phone = relationship("PhoneNumber", active_history=True)

class PhoneNumber(Base):
    __tablename__ = 'phone_number'
    id = Column(Integer(), primary_key=True)
    type = Column(String(20))
    number = Column(String(11))

e = create_engine("sqlite://", echo=True)
Base.metadata.create_all(e)

session = Session(e)

p = Person()
p.name = "Frank"
phone1 = PhoneNumber(type="Mobile", number="1234567890")
phone2 = PhoneNumber(type="Home", number="9876543210")
p.phone = phone1
session.add_all([p, phone1, phone2])
session.commit()
p.phone = phone2
history = inspect(p).attrs.get("phone").history

assert history == ([phone2], (), [phone1])
于 2013-09-04T04:03:20.627 に答える