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+...@googlegroups.com.
To post to this group, send email to sqlal...@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.