On 8/22/15 4:30 PM, Mehdi wrote:
Hi
I'm using latest sqlalchemy with an Oracle db backend.
I have a Date column which presents a /Gregorian date/ in db. but i want to query my table by a /Jalali date/. So the hybrid_property to convert gregorian date into jalali date should be like this, i think:
|
@hybrid_property
defjalali_date(self):
returnjdatetime.date.fromgregorian(year=self.input_date.year,
                                            month=|self.input_date|,
day=|self.input_date.day|)

|

i've tried different ways, but all of them ends with errors like:
|
AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with MeasureData.input_date has an attribute 'year'
or
TypeError: an integer is required (got type InstrumentedAttribute)
|

So i guess i have to get access to *instance value* of /MeasureDate.input_date/ at hybrid_property definition, but How?
Do i have to completely change my approach?

the hybrid allows a Python representation at the object level and a SQL representation at the class level. Your error message involves the term "InstrumentedAttribute", which suggests you are attempting to use this hybrid at the class level (please provide full stack traces to make this clearer). Your hybrid as defined only illustrates instance-level conversions and there's not a simple way to do this conversion at the SQL level especially in Oracle, unless you had some stored procedure which does so.

Therefore, you are probably looking for an in-Python value of a Jalali date to be converted from the alternate calendar to the gregorian (SQL-persisted) calendar *in python*, before it is sent to the database, and converted back to Jalali *in Python* after being received from the database as a result. For this, you want to build a custom type similar to the "MyEpochType" illustrated at http://docs.sqlalchemy.org/en/rel_1_0/core/custom_types.html#augmenting-existing-types - using this type will cause expressions like equality comparisons to coerce the "value side" of the expression, e.g. the raw datetime object, as according to your rules. You can then cause this particular type to be used with your hybrid using type_coerce. Here's an example using most features of hybrids:

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.hybrid import hybrid_property
import jdatetime
import datetime

Base = declarative_base()


class JDate(TypeDecorator):
    impl = Date

    def process_bind_param(self, value, dialect):
        if value is not None:
            value = jdatetime.date.togregorian(value)
        return value

    def process_result_value(self, value, dialect):
        if value is not None:
            value = jdatetime.date.fromgregorian(
                year=value.year,
                month=value.month,
                day=value.day)
        return value


class A(Base):
    __tablename__ = 'a'
    id = Column(Integer, primary_key=True)

    input_date = Column(Date)

    @hybrid_property
    def jalali_date(self):
        return jdatetime.date.fromgregorian(
            year=self.input_date.year,
            month=self.input_date.month,
            day=self.input_date.day)

    @jalali_date.expression
    def jalali_date(cls):
        return type_coerce(cls.input_date, JDate)

    @jalali_date.setter
    def jalali_date(self, value):
        self.input_date = jdatetime.date.togregorian(value)


e = create_engine("postgresql://scott:tiger@localhost/test", echo=True)
Base.metadata.drop_all(e)
Base.metadata.create_all(e)


a1 = A(jalali_date=jdatetime.date(1380, 8, 2))
a2 = A(input_date=datetime.date(2001, 10, 24))

s = Session(e)
s.add_all([a1, a2])
s.commit()
s.close()

a1, a2 = s.query(A).filter_by(jalali_date=jdatetime.date(1380, 8, 2)).all()

print a1.jalali_date, a2.jalali_date
print a1.input_date, a2.input_date



in the output, we can see that jalali_date and input_date are consistent from both ways of setting, both ways of matching:

1380-08-02 1380-08-02
2001-10-24 2001-10-24








Thanks.
--
You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com <mailto:sqlalchemy+unsubscr...@googlegroups.com>. To post to this group, send email to sqlalchemy@googlegroups.com <mailto:sqlalchemy@googlegroups.com>.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to