On Mon, Aug 5, 2019, at 3:21 PM, Michael wrote:
> Thanks a lot! Indeed SQLite seems to be the problem and the code works fine
> with PostgreSQL.
>
> Unfortunately, a full fledged database server is not an option. Therefore I
> probably have to work around the problem in Python.
>
> Is there an easy way to obtain a list of objects generated by multiple
> group_by conditions? Then I could calculate the percentiles e.g. in numpy.
group_by() accepts any number of expressions and you can use it multiple times.
>
> Am Montag, 5. August 2019 18:16:38 UTC+2 schrieb Mike Bayer:
>> does SQLite support WITHIN GROUP ? Try it out on PostgreSQL, I think this is
>> just not syntax SQLite supports.
>>
>>
>> On Mon, Aug 5, 2019, at 10:38 AM, Michael wrote:
>>> Hi!
>>>
>>> I'm really having a great time with sqlalchemy so far!
>>>
>>> Currently I'm trying to apply a percentile function on a ORM schema with
>>> sqlite3. Average, min, max etc are working fine, but i cannot compute the
>>> median or any other percentile using 'percentile_cont'.
>>>
>>> A minimal example and the corresponding error messages can be found below.
>>>
>>> Any help would be greatly appreciated!
>>>
>>> Best
>>> Michael
>>>
>>>
>>> import sqlalchemy
>>> sqlalchemy.__version__ # '1.3.5'
>>>
>>>
>>>
>>> from sqlalchemy import create_engine
>>> engine = create_engine('sqlite:///:memory:', echo=False)
>>>
>>>
>>> from sqlalchemy.ext.declarative import declarative_base
>>> Base = declarative_base()
>>>
>>>
>>> from sqlalchemy import Column, Float, String, Integer
>>> class User(Base):
>>> __tablename__ = 'users'
>>>
>>>
>>> id = Column(Integer, primary_key=True)
>>> name = Column(String)
>>> role = Column(String)
>>> salary = Column(Float)
>>>
>>>
>>> def __repr__(self):
>>> return "<User(name='%s', fullname='%s', nickname='%s')>" % (
>>> self.name, self.fullname, self.nickname)
>>>
>>>
>>>
>>>
>>>
>>>
>>> Base.metadata.create_all(engine)
>>>
>>>
>>> u1 = User(name='u1', role='Manager', salary = 100)
>>> u2 = User(name='u2', role='Manager', salary = 110)
>>> u3 = User(name='u3', role='Employee', salary = 1000)
>>> u4 = User(name='u4', role='Employee', salary = 200)
>>>
>>>
>>>
>>>
>>> from sqlalchemy.orm import sessionmaker
>>> Session = sessionmaker(bind=engine)
>>> session = Session()
>>>
>>>
>>>
>>>
>>> session.add(u1)
>>> session.add(u2)
>>> session.add(u3)
>>> session.add(u4)
>>>
>>>
>>>
>>>
>>> from sqlalchemy.sql import func
>>> from sqlalchemy import within_group
>>>
>>> q1 =
>>> session.query(func.avg(User.salary).label('average')).group_by(User.role)
>>> print(q1.all())
>>> q2 =
>>> session.query(func.percentile_disc(0.5).within_group(User.salary)).group_by(User.role)
>>> print(q2)
>>>
>>>
>>> print(q2.all()) # ERROR
>>>
>>> ---------------------------------------------------------------------------
>>> OperationalError Traceback (most recent call last)
>>> /usr/lib64/python3.7/site-packages/sqlalchemy/engine/base.py in
>>> _execute_context(self, dialect, constructor, statement, parameters, *args)
>>> 1243 self.dialect.do_execute(
>>> -> 1244 cursor, statement, parameters, context
>>> 1245 )
>>>
>>> /usr/lib64/python3.7/site-packages/sqlalchemy/engine/default.py in
>>> do_execute(self, cursor, statement, parameters, context)
>>> 549 def do_execute(self, cursor, statement, parameters,
>>> context=None):
>>> --> 550 cursor.execute(statement, parameters)
>>> 551
>>>
>>> OperationalError: near "(": syntax error
>>>
>>> The above exception was the direct cause of the following exception:
>>>
>>> OperationalError Traceback (most recent call last)
>>> <ipython-input-13-bded0b5cee0a> in <module>
>>> ----> 1 print(q2.all()) # ERROR
>>>
>>> /usr/lib64/python3.7/site-packages/sqlalchemy/orm/query.py in all(self)
>>> 3166
>>> 3167 """
>>> -> 3168 return list(self)
>>> 3169
>>> 3170 @_generative(_no_clauseelement_condition)
>>>
>>> /usr/lib64/python3.7/site-packages/sqlalchemy/orm/query.py in __iter__(self)
>>> 3322 if self._autoflush and not self._populate_existing:
>>> 3323 self.session._autoflush()
>>> -> 3324 return self._execute_and_instances(context)
>>> 3325
>>> 3326 def __str__(self):
>>>
>>> /usr/lib64/python3.7/site-packages/sqlalchemy/orm/query.py in
>>> _execute_and_instances(self, querycontext)
>>> 3347 )
>>> 3348
>>> -> 3349 result = conn.execute(querycontext.statement, self._params)
>>> 3350 return loading.instances(querycontext.query, result,
>>> querycontext)
>>> 3351
>>>
>>> /usr/lib64/python3.7/site-packages/sqlalchemy/engine/base.py in
>>> execute(self, object_, *multiparams, **params)
>>> 986 raise exc.ObjectNotExecutableError(object_)
>>> 987 else:
>>> --> 988 return meth(self, multiparams, params)
>>> 989
>>> 990 def _execute_function(self, func, multiparams, params):
>>>
>>> /usr/lib64/python3.7/site-packages/sqlalchemy/sql/elements.py in
>>> _execute_on_connection(self, connection, multiparams, params)
>>> 285 def _execute_on_connection(self, connection, multiparams,
>>> params):
>>> 286 if self.supports_execution:
>>> --> 287 return connection._execute_clauseelement(self,
>>> multiparams, params)
>>> 288 else:
>>> 289 raise exc.ObjectNotExecutableError(self)
>>>
>>> /usr/lib64/python3.7/site-packages/sqlalchemy/engine/base.py in
>>> _execute_clauseelement(self, elem, multiparams, params)
>>> 1105 distilled_params,
>>> 1106 compiled_sql,
>>> -> 1107 distilled_params,
>>> 1108 )
>>> 1109 if self._has_events or self.engine._has_events:
>>>
>>> /usr/lib64/python3.7/site-packages/sqlalchemy/engine/base.py in
>>> _execute_context(self, dialect, constructor, statement, parameters, *args)
>>> 1246 except BaseException as e:
>>> 1247 self._handle_dbapi_exception(
>>> -> 1248 e, statement, parameters, cursor, context
>>> 1249 )
>>> 1250
>>>
>>> /usr/lib64/python3.7/site-packages/sqlalchemy/engine/base.py in
>>> _handle_dbapi_exception(self, e, statement, parameters, cursor, context)
>>> 1464 util.raise_from_cause(newraise, exc_info)
>>> 1465 elif should_wrap:
>>> -> 1466 util.raise_from_cause(sqlalchemy_exception,
>>> exc_info)
>>> 1467 else:
>>> 1468 util.reraise(*exc_info)
>>>
>>> /usr/lib64/python3.7/site-packages/sqlalchemy/util/compat.py in
>>> raise_from_cause(exception, exc_info)
>>> 397 exc_type, exc_value, exc_tb = exc_info
>>> 398 cause = exc_value if exc_value is not exception else None
>>> --> 399 reraise(type(exception), exception, tb=exc_tb, cause=cause)
>>> 400
>>> 401
>>>
>>> /usr/lib64/python3.7/site-packages/sqlalchemy/util/compat.py in reraise(tp,
>>> value, tb, cause)
>>> 151 value.__cause__ = cause
>>> 152 if value.__traceback__ is not tb:
>>> --> 153 raise value.with_traceback(tb)
>>> 154 raise value
>>> 155
>>>
>>> /usr/lib64/python3.7/site-packages/sqlalchemy/engine/base.py in
>>> _execute_context(self, dialect, constructor, statement, parameters, *args)
>>> 1242 if not evt_handled:
>>> 1243 self.dialect.do_execute(
>>> -> 1244 cursor, statement, parameters, context
>>> 1245 )
>>> 1246 except BaseException as e:
>>>
>>> /usr/lib64/python3.7/site-packages/sqlalchemy/engine/default.py in
>>> do_execute(self, cursor, statement, parameters, context)
>>> 548
>>> 549 def do_execute(self, cursor, statement, parameters,
>>> context=None):
>>> --> 550 cursor.execute(statement, parameters)
>>> 551
>>> 552 def do_execute_no_params(self, cursor, statement, context=None):
>>>
>>> OperationalError: (sqlite3.OperationalError) near "(": syntax error
>>> [SQL: SELECT percentile_cont(?) WITHIN GROUP (ORDER BY users.salary DESC)
>>> AS anon_1
>>> FROM users GROUP BY users.role]
>>> [parameters: (0.5,)]
>>> (Background on this error at: http://sqlalche.me/e/e3q8)
>>>
>>>
>>>
>>> --
>>> SQLAlchemy -
>>> The Python SQL Toolkit and Object Relational Mapper
>>>
>>> http://www.sqlalchemy.org/
>>>
>>> To post example code, please provide an MCVE: Minimal, Complete, and
>>> Verifiable Example. See http://stackoverflow.com/help/mcve for a full
>>> description.
>>> ---
>>> 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 [email protected].
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/sqlalchemy/00f96614-56d4-4cef-9134-632458b5793c%40googlegroups.com
>>>
>>> <https://groups.google.com/d/msgid/sqlalchemy/00f96614-56d4-4cef-9134-632458b5793c%40googlegroups.com?utm_medium=email&utm_source=footer>.
>>
>
> --
> SQLAlchemy -
> The Python SQL Toolkit and Object Relational Mapper
>
> http://www.sqlalchemy.org/
>
> To post example code, please provide an MCVE: Minimal, Complete, and
> Verifiable Example. See http://stackoverflow.com/help/mcve for a full
> description.
> ---
> 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 [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sqlalchemy/2ddea076-cd34-4e16-b786-02766a948c9a%40googlegroups.com
>
> <https://groups.google.com/d/msgid/sqlalchemy/2ddea076-cd34-4e16-b786-02766a948c9a%40googlegroups.com?utm_medium=email&utm_source=footer>.
--
SQLAlchemy -
The Python SQL Toolkit and Object Relational Mapper
http://www.sqlalchemy.org/
To post example code, please provide an MCVE: Minimal, Complete, and Verifiable
Example. See http://stackoverflow.com/help/mcve for a full description.
---
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 [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/sqlalchemy/1b1a6107-871f-4cec-9158-097427c8d352%40www.fastmail.com.