note , . :
raw sql , .
- :
LEAST(GREATEST(SUM(myfield) OVER (window_clause), lower_bound), upper_bound)
sqlalchemy ,
import sqlalchemy as sa
import sqlalchemy.ext.declarative as dec
base = dec.declarative_base()
class Foo(base):
__tablename__ = 'foo'
id = sa.Column(sa.Integer, primary_key=True)
points = sa.Column(sa.Integer, nullable=False)
timestamp = sa.Column('tstamp', sa.Integer)
upper_, lower_ = 100, -100
win_expr = func.sum(Foo.points).over(order_by=Foo.timestamp)
bound_expr = sa.func.least(sa.func.greatest(win_expr, lower_), upper_).label('bounded_running_total')
stmt = sa.select([Foo.id, Foo.points, Foo.timestamp, bound_expr])
str(stmt)
from sqlalchemy.orm sessionmaker
DB = sessionmaker()
db = DB()
foos_stmt = dm.query(Foo.id, Foo.points, Foo.timestamp, bound_expr).filter(...)
str(foos_stmt)
foos = foos_stmt.all()
EDIT @pozs , .
@pozs. , sqlalchemy.
import sqlalchemy as sa
import sqlalchemy.ext.declarative as dec
import sqlalchemy.orm as orm
base = dec.declarative_base()
class Foo(base):
__tablename__ = 'foo'
id = sa.Column(sa.Integer, primary_key=True)
points = sa.Column(sa.Integer, nullable=False)
timestamp = sa.Column('tstamp', sa.Integer)
upper_, lower_ = 100, -100
t = sa.select([
Foo.timestamp,
Foo.points,
Foo.points.label('bounded_running_sum')
]).order_by(Foo.timestamp).limit(1).cte('t', recursive=True)
t_aliased = orm.aliased(t, name='ta')
bounded_sum = t.union_all(
sa.select([
Foo.timestamp,
Foo.points,
sa.func.greatest(sa.func.least(Foo.points + t_aliased.c.bounded_running_sum, upper_), lower_)
]).order_by(Foo.timestamp).limit(1)
)
stmt = sa.select([bounded_sum])
from sqlalchemy.dialects import postgresql
print(stmt.compile(dialect=postgresql.dialect(),
compile_kwargs={'literal_binds': True}))
, , CTE
sqlalchemy .
, @pozs, sqlalchemy.
source
share