Python Postgres在SQLAlchemy中用作列

Python Postgres在SQLAlchemy中用作列,python,postgresql,sqlalchemy,Python,Postgresql,Sqlalchemy,我在Postgesql数据库中有两个函数: id\u生成器,它根据时间戳生成id timestamp\u from\u id(id),它将id反转为时间戳 假设这是我的模型: class DatModel(object): id = Column( BigInteger, primary_key=True, server_default=text('id_generator()') ) name = Column(Str

我在Postgesql数据库中有两个函数:

  • id\u生成器
    ,它根据时间戳生成id
  • timestamp\u from\u id(id)
    ,它将id反转为时间戳
假设这是我的模型:

class DatModel(object):
    id = Column(
        BigInteger,
        primary_key=True,
        server_default=text('id_generator()')
    )
    name = Column(String(50), index=True)
我想做的是通过
timestamp
从\u id(id)函数生成的
timestamp\u进行查询,例如:

dbsession.query(DatModel).filter(DatModel.timestamp > datetime.now()).all()
class DatModel(object):
    id = Column(
        BigInteger,
        primary_key=True,
        server_default=text('id_generator()')
    )
    name = Column(String(50), index=True)
    timestamp = column_property(literal_column("timestamp_from_id(datmodel.id)", type_=DateTime).label('timestamp'))

我的问题是:

如何基于postgres函数创建虚拟栏目

提前谢谢


编辑:

不满意的方法#1 尽可能的解决方法是使用。这是一种工作方法,但在检索时间戳时问题不大:

timestamp = session.execute(func.timestamp_from_id(obj.id)).fetchone()
我更喜欢这样做:

timestamp = obj.timestamp
不满意的方法#2 第二种可能的解决办法是使用

从日期时间导入日期时间
从sqlalchemy导入日期时间
从sqlalchemy.ext.compiler导入编译
从sqlalchemy.sql.functions导入FunctionElement
类时间戳(FunctionElement):
类型=日期时间()
名称='时间戳'
@编译(时间戳)
def default_时间戳(元素,编译器,**kw):
返回编译器。访问函数(元素)
@编译(时间戳“postgresql”)
已创建def pg_(元素、编译器,**kw):
arg1=列表(元素.子句)[0]
返回'timestamp_from_id({})'.format(compiler.process(arg1))
#过滤示例
obj=session.query(DatModel).filter(Timestamp
如果我正确理解了您的问题,您可以使用
func
从\u id
调用存储过程
timestamp\u

所以你会得到这样的结果:

from sqlalchemy import func

# some code here

dbsession.query(DatModel).filter(func.timestamp_from_id(DataModel.id) > datetime.now()).all()

# some code here
没有尝试代码。可能您也应该从\u id(DataModel.id).scalar()执行
func.timestamp\u


您可以找到和查看更多信息。

如果我正确理解您的问题,您可以使用
func
从\u id
调用存储过程
timestamp\u

所以你会得到这样的结果:

from sqlalchemy import func

# some code here

dbsession.query(DatModel).filter(func.timestamp_from_id(DataModel.id) > datetime.now()).all()

# some code here
没有尝试代码。可能您也应该从\u id(DataModel.id).scalar()执行
func.timestamp\u

您可以找到和查看更多信息。

请阅读SQL表达式作为映射属性文档的一节

使用它,您应该能够做到:

class DatModel(Base):
    id = Column(
        Integer,
        primary_key=True,
        server_default=text('id_generator()')
    )
    name = Column(String(50), index=True)

    timestamp = column_property(func.timestamp_from_id(id))
时间戳
也将包含在查询中,您可以在筛选和/或排序表达式中使用它:

q = (session.query(DatModel)
     .filter(DatModel.timestamp > datetime.now())
     .order_by(DatModel.timestamp.desc())
    )
请阅读SQL表达式作为映射属性文档的一节

使用它,您应该能够做到:

class DatModel(Base):
    id = Column(
        Integer,
        primary_key=True,
        server_default=text('id_generator()')
    )
    name = Column(String(50), index=True)

    timestamp = column_property(func.timestamp_from_id(id))
时间戳
也将包含在查询中,您可以在筛选和/或排序表达式中使用它:

q = (session.query(DatModel)
     .filter(DatModel.timestamp > datetime.now())
     .order_by(DatModel.timestamp.desc())
    )

解决方案是使用
混合属性
表达式
()

用法示例:

obj = DatModel()
with transaction.manager:
    session.add(obj)
obj = session.query(DatModel).one()

assert type(obj.timestamp) == datetime.datetime
assert obj.timestamp.date() == datetime.date.today()


objs = session.query(DatModel) \
    .filter(DatModel.timestamp < datetime.datetime.now())
assert objs.count() == 1

objs = session.query(Gateway) \
    .filter(DatModel.timestamp > datetime.datetime.now())
assert objs.count() == 0
obj=DatModel()
使用transaction.manager:
会话.添加(obj)
obj=session.query(DatModel).one()
断言类型(obj.timestamp)=datetime.datetime
assert obj.timestamp.date()==datetime.date.today()
objs=session.query(DatModel)\
.filter(DatModel.timestampdatetime.datetime.now())
断言objs.count()==0

解决方案是使用
混合属性
表达式
()

用法示例:

obj = DatModel()
with transaction.manager:
    session.add(obj)
obj = session.query(DatModel).one()

assert type(obj.timestamp) == datetime.datetime
assert obj.timestamp.date() == datetime.date.today()


objs = session.query(DatModel) \
    .filter(DatModel.timestamp < datetime.datetime.now())
assert objs.count() == 1

objs = session.query(Gateway) \
    .filter(DatModel.timestamp > datetime.datetime.now())
assert objs.count() == 0
obj=DatModel()
使用transaction.manager:
会话.添加(obj)
obj=session.query(DatModel).one()
断言类型(obj.timestamp)=datetime.datetime
assert obj.timestamp.date()==datetime.date.today()
objs=session.query(DatModel)\
.filter(DatModel.timestampdatetime.datetime.now())
断言objs.count()==0

您可以使用一个带有。例如:

dbsession.query(DatModel).filter(DatModel.timestamp > datetime.now()).all()
class DatModel(object):
    id = Column(
        BigInteger,
        primary_key=True,
        server_default=text('id_generator()')
    )
    name = Column(String(50), index=True)
    timestamp = column_property(literal_column("timestamp_from_id(datmodel.id)", type_=DateTime).label('timestamp'))

您可以使用一个带有一个的。例如:

dbsession.query(DatModel).filter(DatModel.timestamp > datetime.now()).all()
class DatModel(object):
    id = Column(
        BigInteger,
        primary_key=True,
        server_default=text('id_generator()')
    )
    name = Column(String(50), index=True)
    timestamp = column_property(literal_column("timestamp_from_id(datmodel.id)", type_=DateTime).label('timestamp'))

这是可能的,这个解决方案是有效的,但对我来说不是。我有一个mixin模型和列属性给了我一个错误:
InvalidRequestError:Mapper属性(即,deferred、column_property()、relationship()等)必须在声明性mixin类上声明为@declarated_attr callables。
但这让我找到了正确的解决方案。非常感谢你!这是可能的,这个解决方案是有效的,但对我来说不是。我有一个mixin模型和列属性给了我一个错误:
InvalidRequestError:Mapper属性(即,deferred、column_property()、relationship()等)必须在声明性mixin类上声明为@declarated_attr callables。
但这让我找到了正确的解决方案。非常感谢你!