2013-08-07 4 views
8

या मैं यह काम कैसे कर सकता हूं?मैं स्क्लाक्लेमी में एक नल कोलेसिंग ऑपरेटर कैसे कार्यान्वित करूं?

class Interval(Base): 
    __tablename__ = 'intervals' 
    id = Column(Integer, primary_key=True) 
    start = Column(DateTime) 
    end = Column(DateTime, nullable=True) 
    task_id = Column(Integer, ForeignKey('tasks.id')) 

@hybrid_property #used to just be @property 
def hours_spent(self): 
    end = self.end or datetime.datetime.now() 
    return (end-start).total_seconds()/60/60 

और एक कार्य:

class Task(Base): 
    __tablename__ = 'tasks' 
    id = Column(Integer, primary_key=True) 
    title = Column(String) 
    intervals = relationship("Interval", backref="task") 

@hybrid_property # Also used to be just @property 
def hours_spent(self): 
    return sum(i.hours_spent for i in self.intervals) 

ज़ाहिर है, सब ठेठ सेटअप कोड जोड़ें

मैं एक अंतराल वस्तु है।

अब जब मैं session.query(Task).filter(Task.hours_spent > 3).all()

मैं sum(i.hours_spent... लाइन से NotImplementedError: <built-in function getitem> प्राप्त करने की कोशिश।

तो मैं प्रलेखन के this part पर देख रहा था और सिद्धांत दिया कि कुछ ऐसा तरीका हो सकता है जो मैं कुछ लिखूं जो मैं चाहता हूं। This part भी है जैसे कि यह काम का हो सकता है लग रहा है, और मैं थोड़ी देर के लिए यहाँ एक जवाब के लिए इंतजार इसे देख हो जाएगा;)

उत्तर

5

SQLAlchemy बहुत चालाक इन ऑपरेंड से एसक्यूएल अभिव्यक्ति पेड़ के निर्माण के लिए नहीं है, आप स्पष्ट का उपयोग करने के propname.expression इसे प्रदान करने के लिए सजावटी। लेकिन फिर एक और समस्या आती है: डेटाबेस में घंटे के अंतराल को बदलने के लिए कोई पोर्टेबल तरीका नहीं है। आप PostgreSQL आदि में MySQL, EXTRACT(EPOCH FROM ...)/3600 में TIMEDIFF का उपयोग करेंगे। मैं बदले में गुणों को बदलने के लिए timedelta और सेब की तुलना सेब की तुलना करने के लिए बदलता हूं।

from sqlalchemy import select, func 


class Interval(Base): 
    ... 

    @hybrid_property 
    def time_spent(self): 
     return (self.end or datetime.now()) - self.start 

    @time_spent.expression 
    def time_spent(cls): 
     return func.coalesce(cls.end, func.current_timestamp()) - cls.start 


class Task(Base): 
    ... 

    @hybrid_property 
    def time_spent(self): 
     return sum((i.time_spent for i in self.intervals), timedelta(0)) 

    @time_spent.expression 
    def hours_spent(cls): 
     return (select([func.sum(Interval.time_spent)]) 
      .where(cls.id==Interval.task_id) 
      .label('time_spent')) 

अंतिम क्वेरी है:

session.query(Task).filter(Task.time_spent > timedelta(hours=3)).all() 

जो करने के लिए (PostgreSQL बैकएंड पर) अनुवाद:

SELECT task.id AS task_id, task.title AS task_title 
FROM task 
WHERE (SELECT sum(coalesce(interval."end", CURRENT_TIMESTAMP) - interval.start) AS sum_1 
FROM interval 
WHERE task.id = interval.task_id) > %(param_1)s 
3

SQLAlchemy का सम्मिलित समारोह का एक सरल उदाहरण के लिए, यह मदद मिल सकती है: Handling null values in a SQLAlchemy query - equivalent of isnull, nullif or coalesce

from sqlalchemy.sql.functions import coalesce 
my_config = session.query(Config).order_by(coalesce(Config.last_processed_at, datetime.date.min)).first() 
+2

मुझे लगता है कि इस लिंक बेहतर काम करेगा:

यहाँ कि पद से कोड के प्रमुख लाइनों के एक जोड़े हैं http://progblog10.blogspot.com/2014/06/handling-null-values -in-sqlalchemy.html – Kirk

+0

आप सही हैं! उस लिंक को ठीक करने के लिए धन्यवाद। –

संबंधित मुद्दे