Hello community, here is the log from the commit of package python-python-sql for openSUSE:Factory checked in at 2017-04-26 21:43:39 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-python-sql (Old) and /work/SRC/openSUSE:Factory/.python-python-sql.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "python-python-sql" Wed Apr 26 21:43:39 2017 rev:2 rq:490298 version:0.9 Changes: -------- --- /work/SRC/openSUSE:Factory/python-python-sql/python-python-sql.changes 2016-07-14 09:45:00.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.python-python-sql.new/python-python-sql.changes 2017-04-26 21:43:44.207555897 +0200 @@ -1,0 +2,14 @@ +Mon Apr 24 11:49:18 UTC 2017 - axel.braun@gmx.de + +- Version 0.9 + * Add distinct_on on Select + * Allow to use Select as Column of Select query + * Support Select without from clause + +------------------------------------------------------------------- +Mon Apr 17 08:32:08 UTC 2017 - axel.braun@gmx.de + +- singlespec + source URL corrected + +------------------------------------------------------------------- Old: ---- python-sql-0.8.tar.gz New: ---- python-sql-0.9.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-python-sql.spec ++++++ --- /var/tmp/diff_new_pack.9ECvYA/_old 2017-04-26 21:43:46.103288273 +0200 +++ /var/tmp/diff_new_pack.9ECvYA/_new 2017-04-26 21:43:46.115286579 +0200 @@ -1,7 +1,7 @@ # -# spec file for package python +# spec file for package python-python-sql # -# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -15,13 +15,16 @@ # Please submit bugfixes or comments via http://bugs.opensuse.org/ # +%{?!python_module:%define python_module() python-%{**} python3-%{**}} + %define base_name python-sql Name: python-%{base_name} -BuildRequires: python-devel -BuildRequires: python-setuptools -Version: 0.8 +BuildRequires: %{python_module devel} +BuildRequires: %{python_module setuptools} +BuildRequires: python-rpm-macros +Version: 0.9 Release: 0 -Source: https://files.pythonhosted.org/packages/c5/4b/c8c15049bc683428c8248eb37a0f22e9ad20e7853f8215ca8deb023ed689/%{base_name}-%{version}.tar.gz +Source: https://pypi.io/packages/source/p/%{base_name}/%{base_name}-%{version}.tar.gz Url: https://pypi.io/project/python-sql %if 0%{?suse_version} && 0%{?suse_version} <= 1110 %{!?python_sitelib: %global python_sitelib %(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} @@ -31,7 +34,8 @@ Summary: Library to write SQL queries License: BSD-3-Clause Group: Development/Languages/Python -BuildRoot: %{_tmppath}/%{base_name}-%{version}-build +BuildRoot: %{_tmppath}/%{name}-%{version}-build +%python_subpackages %description python-sql is a library to write SQL queries in a pythonic way. @@ -40,12 +44,12 @@ %setup -q -n %{base_name}-%{version} %build -python setup.py build +%python_build %install -python setup.py install --prefix=%_prefix --root=%buildroot +%python_install -%files +%files %{python_files} %defattr(-,root,root) %doc README %{python_sitelib}/* ++++++ python-sql-0.8.tar.gz -> python-sql-0.9.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-sql-0.8/CHANGELOG new/python-sql-0.9/CHANGELOG --- old/python-sql-0.8/CHANGELOG 2015-09-19 15:22:48.000000000 +0200 +++ new/python-sql-0.9/CHANGELOG 2017-04-24 12:17:09.000000000 +0200 @@ -1,3 +1,8 @@ +Version 0.9 - 2017-04-24 +* Add distinct_on on Select +* Allow to use Select as Column of Select query +* Support Select without from clause + Version 0.8 - 2015-09-19 * Add DISTINCT qualifier to aggregate expressions * Allow to order on select queries diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-sql-0.8/PKG-INFO new/python-sql-0.9/PKG-INFO --- old/python-sql-0.8/PKG-INFO 2015-09-19 15:23:39.000000000 +0200 +++ new/python-sql-0.9/PKG-INFO 2017-04-24 12:19:14.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: python-sql -Version: 0.8 +Version: 0.9 Summary: Library to write SQL queries Home-page: http://python-sql.tryton.org/ Author: B2CK @@ -192,6 +192,7 @@ ('SELECT "a".* FROM (SELECT "b".*, ROWNUM AS "rnum" FROM (SELECT * FROM "user" AS "c") AS "b" WHERE (ROWNUM <= %s)) AS "a" WHERE ("rnum" > %s)', (30, 20)) qmark style:: + >>> Flavor.set(Flavor(paramstyle='qmark')) >>> select = user.select() >>> select.where = user.name == 'foo' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-sql-0.8/README new/python-sql-0.9/README --- old/python-sql-0.8/README 2015-06-22 15:48:04.000000000 +0200 +++ new/python-sql-0.9/README 2015-09-19 15:25:09.000000000 +0200 @@ -184,6 +184,7 @@ ('SELECT "a".* FROM (SELECT "b".*, ROWNUM AS "rnum" FROM (SELECT * FROM "user" AS "c") AS "b" WHERE (ROWNUM <= %s)) AS "a" WHERE ("rnum" > %s)', (30, 20)) qmark style:: + >>> Flavor.set(Flavor(paramstyle='qmark')) >>> select = user.select() >>> select.where = user.name == 'foo' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-sql-0.8/python_sql.egg-info/PKG-INFO new/python-sql-0.9/python_sql.egg-info/PKG-INFO --- old/python-sql-0.8/python_sql.egg-info/PKG-INFO 2015-09-19 15:23:31.000000000 +0200 +++ new/python-sql-0.9/python_sql.egg-info/PKG-INFO 2017-04-24 12:19:12.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: python-sql -Version: 0.8 +Version: 0.9 Summary: Library to write SQL queries Home-page: http://python-sql.tryton.org/ Author: B2CK @@ -192,6 +192,7 @@ ('SELECT "a".* FROM (SELECT "b".*, ROWNUM AS "rnum" FROM (SELECT * FROM "user" AS "c") AS "b" WHERE (ROWNUM <= %s)) AS "a" WHERE ("rnum" > %s)', (30, 20)) qmark style:: + >>> Flavor.set(Flavor(paramstyle='qmark')) >>> select = user.select() >>> select.where = user.name == 'foo' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-sql-0.8/sql/__init__.py new/python-sql-0.9/sql/__init__.py --- old/python-sql-0.8/sql/__init__.py 2015-07-28 16:33:51.000000000 +0200 +++ new/python-sql-0.9/sql/__init__.py 2016-09-14 11:25:03.000000000 +0200 @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- # -# Copyright (c) 2011-2015, Cédric Krier +# Copyright (c) 2011-2016, Cédric Krier # Copyright (c) 2013-2014, Nicolas Évrard -# Copyright (c) 2011-2015, B2CK +# Copyright (c) 2011-2016, B2CK # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -29,7 +29,7 @@ from __future__ import division -__version__ = '0.8' +__version__ = '0.9' __all__ = ['Flavor', 'Table', 'Values', 'Literal', 'Column', 'Join', 'Asc', 'Desc', 'NullsFirst', 'NullsLast', 'format2numeric'] @@ -37,6 +37,7 @@ import warnings from threading import local, currentThread from collections import defaultdict +from itertools import chain def alias(i, letters=string.ascii_lowercase): @@ -293,7 +294,7 @@ super(With, self).__init__(**kwargs) def statement(self): - columns = ('(%s)' % ', '.join('"%s"' % c for c in self.columns) + columns = (' (%s)' % ', '.join('"%s"' % c for c in self.columns) if self.columns else '') return '"%s"%s AS (%s)' % (self.alias, columns, self.query) @@ -382,20 +383,24 @@ fetch = ' FETCH FIRST (%s) ROWS ONLY' % self.limit return offset + fetch + def as_(self, output_name): + return As(self, output_name) + class Select(FromItem, SelectQuery): __slots__ = ('_columns', '_where', '_group_by', '_having', '_for_', - 'from_') + 'from_', '_distinct_on') def __init__(self, columns, from_=None, where=None, group_by=None, - having=None, for_=None, **kwargs): + having=None, for_=None, distinct_on=None, **kwargs): + self._distinct_on = None self._columns = None self._where = None self._group_by = None self._having = None self._for_ = None super(Select, self).__init__(**kwargs) - # TODO ALL|DISTINCT + self.distinct_on = distinct_on self.columns = columns self.from_ = from_ self.where = where @@ -404,12 +409,24 @@ self.for_ = for_ @property + def distinct_on(self): + return self._distinct_on + + @distinct_on.setter + def distinct_on(self, value): + if value is not None: + if isinstance(value, Expression): + value = [value] + assert all(isinstance(col, Expression) for col in value) + self._distinct_on = value + + @property def columns(self): return self._columns @columns.setter def columns(self, value): - assert all(isinstance(col, Expression) for col in value) + assert all(isinstance(col, (Expression, SelectQuery)) for col in value) self._columns = tuple(value) @property @@ -461,12 +478,19 @@ @staticmethod def _format_column(column): if isinstance(column, As): + if isinstance(column.expression, Select): + expression = '(%s)' % column.expression + else: + expression = column.expression if Flavor.get().no_as: - return '%s %s' % (column.expression, column) + return '%s %s' % (expression, column) else: - return '%s AS %s' % (column.expression, column) + return '%s AS %s' % (expression, column) else: - return str(column) + if isinstance(column, Select): + return '(%s)' % column + else: + return str(column) def _window_functions(self): from sql.functions import WindowFunction @@ -528,7 +552,15 @@ return self._rownum(str) with AliasManager(): - from_ = str(self.from_) + if self.from_ is not None: + from_ = ' FROM %s' % self.from_ + else: + from_ = '' + if self.distinct_on is not None: + distinct_on = ('DISTINCT ON (%s) ' + % ', '.join(map(str, self.distinct_on))) + else: + distinct_on = '' if self.columns: columns = ', '.join(map(self._format_column, self.columns)) else: @@ -551,7 +583,7 @@ if self.for_ is not None: for_ = ' ' + ' '.join(map(str, self.for_)) return (self._with_str() - + 'SELECT %s FROM %s' % (columns, from_) + + 'SELECT %s%s%s' % (distinct_on, columns, from_) + where + group_by + having + window + self._order_by_str + self._limit_offset_str + for_) @@ -562,11 +594,12 @@ return self._rownum(lambda q: q.params) p = [] p.extend(self._with_params()) - for column in self.columns: + for column in chain(self.distinct_on or (), self.columns): if isinstance(column, As): p.extend(column.expression.params) p.extend(column.params) - p.extend(self.from_.params) + if self.from_ is not None: + p.extend(self.from_.params) if self.where: p.extend(self.where.params) if self.group_by: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-sql-0.8/sql/tests/test_select.py new/python-sql-0.9/sql/tests/test_select.py --- old/python-sql-0.8/sql/tests/test_select.py 2015-06-22 15:41:07.000000000 +0200 +++ new/python-sql-0.9/sql/tests/test_select.py 2016-09-14 11:25:17.000000000 +0200 @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- # -# Copyright (c) 2011-2015, Cédric Krier +# Copyright (c) 2011-2016, Cédric Krier # Copyright (c) 2013-2014, Nicolas Évrard -# Copyright (c) 2011-2015, B2CK +# Copyright (c) 2011-2016, B2CK # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -59,6 +59,34 @@ 'SELECT * FROM "t" AS "a" WHERE ("a"."c" = %s)') self.assertEqual(query.params, ('foo',)) + def test_select_without_from(self): + query = Select([Literal(1)]) + self.assertEqual(str(query), 'SELECT %s') + self.assertEqual(query.params, (1,)) + + def test_select_select(self): + query = Select([Select([Literal(1)])]) + self.assertEqual(str(query), 'SELECT (SELECT %s)') + self.assertEqual(query.params, (1,)) + + def test_select_select_as(self): + query = Select([Select([Literal(1)]).as_('foo')]) + self.assertEqual(str(query), 'SELECT (SELECT %s) AS "foo"') + self.assertEqual(query.params, (1,)) + + def test_select_distinct_on(self): + query = self.table.select(self.table.c, distinct_on=self.table.c) + self.assertEqual( + str(query), 'SELECT DISTINCT ON ("a"."c") "a"."c" FROM "t" AS "a"') + self.assertEqual(query.params, ()) + + query = self.table.select( + self.table.c, distinct_on=[self.table.a, self.table.b]) + self.assertEqual( + str(query), + 'SELECT DISTINCT ON ("a"."a", "a"."b") "a"."c" FROM "t" AS "a"') + self.assertEqual(query.params, ()) + def test_select_from_list(self): t2 = Table('t2') t3 = Table('t3') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-sql-0.8/sql/tests/test_with.py new/python-sql-0.9/sql/tests/test_with.py --- old/python-sql-0.8/sql/tests/test_with.py 2015-02-01 23:32:20.000000000 +0100 +++ new/python-sql-0.9/sql/tests/test_with.py 2015-09-26 16:20:58.000000000 +0200 @@ -50,7 +50,7 @@ second = With('a', query=self.table.select(self.table.a)) self.assertEqual(second.statement(), - '"a"("a") AS (' + '"a" ("a") AS (' 'SELECT "b"."a" FROM "t" AS "b"' ')') self.assertEqual(second.statement_params(), ()) @@ -82,7 +82,7 @@ q = upto10.select(with_=[upto10]) self.assertEqual(str(q), - 'WITH RECURSIVE "a"("n") AS (' + 'WITH RECURSIVE "a" ("n") AS (' 'VALUES (%s) ' 'UNION ALL ' 'SELECT ("a"."n" + %s) FROM "a" AS "a" WHERE ("a"."n" < %s)'