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.