I have two functions in Postgesql database:
id_generator
, which generates id from timestamptimestamp_from_id(id)
, which reverses id to timestamp
Let's assume this is my model:
class DatModel(object):
id = Column(
BigInteger,
primary_key=True,
server_default=text('id_generator()')
)
name = Column(String(50), index=True)
What I want to do is query by timestamp
generated by timestamp_from_id(id)
function, for example:
dbsession.query(DatModel).filter(DatModel.timestamp > datetime.now()).all()
or
obj = dbsession.query(DatModel).first()
created = obj.timestamp
My question is:
How to create virtual column based on postgres function?
Thanks in advance
Edit:
Unsatisfying method #1
As Roman Dryndik suggested possible solution is to use func. It's working method, but little problematic way while retrieving timestamp:
timestamp = session.execute(func.timestamp_from_id(obj.id)).fetchone()
I'd prefer to do it something like:
timestamp = obj.timestamp
Unsatisfying method #2
Second possible solution is to use Compilation Extension
from datetime import datetime
from sqlalchemy import DateTime
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.sql.functions import FunctionElement
class Timestamp(FunctionElement):
type = DateTime()
name = 'timestamp'
@compiles(Timestamp)
def default_timestamp(element, compiler, **kw):
return compiler.visit_function(element)
@compiles(Timestamp, 'postgresql')
def pg_created(element, compiler, **kw):
arg1 = list(element.clauses)[0]
return 'timestamp_from_id({})'.format(compiler.process(arg1))
# filter example
obj = session.query(DatModel).filter(Timestamp < datetime.now()).first()
# get timestamp attribute example
timestamp = session.execute(Timestamp(obj.id)).fetchone()