3

Duration.create_duration_field()さまざまなパラメーターを使用して呼び出し、クラスで複数のパラメーターを作成できるようにしたいと考えていますhybrid_property。唯一の違いは、それらのそれぞれに対して異なるタイムスタンプが差し引かれることです。

もちろん、使用declarative_attrは必須ではありませんが、プロパティを s にする必要がありますhybrid_property

import datetime
from sqlalchemy import create_engine, MetaData
from sqlalchemy import Column, String, DateTime, Integer
from sqlalchemy.ext.declarative import declarative_base, declared_attr
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import sessionmaker


metadata = MetaData()
Base = declarative_base(metadata=metadata)


class Duration(Base):
    __tablename__ = "duration"

    pk = Column(Integer, primary_key=True)
    name = Column(String, nullable=False)
    notes = Column(String)
    timestamp_initiated = Column(DateTime,
                                default=datetime.datetime.now(),
                                nullable=False)
    timestamp_done = Column(DateTime)

    def __unicode__(self):
        return self.name

    @declared_attr
    def duration(cls):
        return cls.create_duration_field("initiated", "done")

    @classmethod
    def create_duration_field(cls, start, end):
        @hybrid_property
        def duration(obj):
            getattr(obj, "timestamp_%s" % end) - getattr(obj, "timestamp_%s" % start)
        @duration.expression
        def duration(cls):
            return getattr(cls, "timestamp_%s" % end) - getattr(cls, "timestamp_%s" % start)
        return duration



engine = create_engine('sqlite:///:memory:', echo=True)
metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()

duration = Duration(name="Test", timestamp_done=datetime.datetime.now() + datetime.timedelta(seconds=25))
session.add(duration)
session.commit()

assert isinstance(duration.duration, datetime.timedelta)

現在duration.durationはへの参照ですhybrid_property

<sqlalchemy.ext.hybrid.hybrid_property object at 0x1d02190>
4

2 に答える 2

0

私はまだ0.6にいるので、あなたの派手なプロパティを試すことはできません。:)

しかし、代わりに

class Duration(Base):
    # [...] 
    @declared_attr
    def duration(cls):
        return cls.create_duration_field("initiated", "done")

次のようなことを試すことができます:

class Duration(Base):

    duration = declared_attr(create_duration_field("initiated", "done"))

*create_duration_field*クラスメソッドをそのクラスから移動します。そうすれば、別のクラスで再利用することもできます。おそらくdeclared_attrも*create_duration_field*内に移動する必要があり、そこで実験する必要があります。

例として、私がいつも使用しているこの小さなものがあります。

def constructor(**kw):                                                          
    """Creates a class constructor class method"""
    def load(cls):
        query = cls.query
        return query.filter_by(**kw).one()
    return classmethod(load)

次のように使用します。

class SomeModel(Base):

    SomeInstance = constructor(primary_key=17)

instance = SomeModel.SomeInstance()

あなたがアイデアを得ることを願っています。

于 2011-07-13T14:27:19.223 に答える