commit python-SQLAlchemy-Utils for openSUSE:Factory
Hello community, here is the log from the commit of package python-SQLAlchemy-Utils for openSUSE:Factory checked in at 2018-10-15 09:46:43 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-SQLAlchemy-Utils (Old) and /work/SRC/openSUSE:Factory/.python-SQLAlchemy-Utils.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "python-SQLAlchemy-Utils" Mon Oct 15 09:46:43 2018 rev:13 rq:641950 version:0.33.6 Changes: -------- --- /work/SRC/openSUSE:Factory/python-SQLAlchemy-Utils/python-SQLAlchemy-Utils.changes 2018-09-26 14:24:56.585776677 +0200 +++ /work/SRC/openSUSE:Factory/.python-SQLAlchemy-Utils.new/python-SQLAlchemy-Utils.changes 2018-10-15 09:47:56.871069559 +0200 @@ -1,0 +2,7 @@ +Sun Oct 14 15:24:01 UTC 2018 - Arun Persaud <arun@gmx.de> + +- update to version 0.33.6: + * Fixed passlib compatibility issue (again) (#342) + * Added support for SQL VIEWs + +------------------------------------------------------------------- Old: ---- SQLAlchemy-Utils-0.33.5.tar.gz New: ---- SQLAlchemy-Utils-0.33.6.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-SQLAlchemy-Utils.spec ++++++ --- /var/tmp/diff_new_pack.4ovrdq/_old 2018-10-15 09:47:59.411066735 +0200 +++ /var/tmp/diff_new_pack.4ovrdq/_new 2018-10-15 09:47:59.415066731 +0200 @@ -18,7 +18,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-SQLAlchemy-Utils -Version: 0.33.5 +Version: 0.33.6 Release: 0 Summary: Various utility functions for SQLAlchemy License: BSD-3-Clause ++++++ SQLAlchemy-Utils-0.33.5.tar.gz -> SQLAlchemy-Utils-0.33.6.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SQLAlchemy-Utils-0.33.5/CHANGES.rst new/SQLAlchemy-Utils-0.33.6/CHANGES.rst --- old/SQLAlchemy-Utils-0.33.5/CHANGES.rst 2018-09-20 09:34:38.000000000 +0200 +++ new/SQLAlchemy-Utils-0.33.6/CHANGES.rst 2018-10-14 09:08:52.000000000 +0200 @@ -4,6 +4,13 @@ Here you can see the full list of changes between each SQLAlchemy-Utils release. +0.33.6 (2018-10-14) +^^^^^^^^^^^^^^^^^^^ + +- Fixed passlib compatibility issue (again) (#342) +- Added support for SQL VIEWs + + 0.33.5 (2018-09-19) ^^^^^^^^^^^^^^^^^^^ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SQLAlchemy-Utils-0.33.5/PKG-INFO new/SQLAlchemy-Utils-0.33.6/PKG-INFO --- old/SQLAlchemy-Utils-0.33.5/PKG-INFO 2018-09-20 09:39:00.000000000 +0200 +++ new/SQLAlchemy-Utils-0.33.6/PKG-INFO 2018-10-14 09:21:45.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: SQLAlchemy-Utils -Version: 0.33.5 +Version: 0.33.6 Summary: Various utility functions for SQLAlchemy. Home-page: https://github.com/kvesteri/sqlalchemy-utils Author: Konsta Vesterinen, Ryan Leckey, Janne Vanhala, Vesa Uimonen diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SQLAlchemy-Utils-0.33.5/SQLAlchemy_Utils.egg-info/PKG-INFO new/SQLAlchemy-Utils-0.33.6/SQLAlchemy_Utils.egg-info/PKG-INFO --- old/SQLAlchemy-Utils-0.33.5/SQLAlchemy_Utils.egg-info/PKG-INFO 2018-09-20 09:39:00.000000000 +0200 +++ new/SQLAlchemy-Utils-0.33.6/SQLAlchemy_Utils.egg-info/PKG-INFO 2018-10-14 09:21:45.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: SQLAlchemy-Utils -Version: 0.33.5 +Version: 0.33.6 Summary: Various utility functions for SQLAlchemy. Home-page: https://github.com/kvesteri/sqlalchemy-utils Author: Konsta Vesterinen, Ryan Leckey, Janne Vanhala, Vesa Uimonen diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SQLAlchemy-Utils-0.33.5/SQLAlchemy_Utils.egg-info/SOURCES.txt new/SQLAlchemy-Utils-0.33.6/SQLAlchemy_Utils.egg-info/SOURCES.txt --- old/SQLAlchemy-Utils-0.33.5/SQLAlchemy_Utils.egg-info/SOURCES.txt 2018-09-20 09:39:00.000000000 +0200 +++ new/SQLAlchemy-Utils-0.33.6/SQLAlchemy_Utils.egg-info/SOURCES.txt 2018-10-14 09:21:45.000000000 +0200 @@ -41,7 +41,6 @@ sqlalchemy_utils/generic.py sqlalchemy_utils/i18n.py sqlalchemy_utils/listeners.py -sqlalchemy_utils/materialized_view.py sqlalchemy_utils/models.py sqlalchemy_utils/observer.py sqlalchemy_utils/operators.py @@ -49,6 +48,7 @@ sqlalchemy_utils/proxy_dict.py sqlalchemy_utils/query_chain.py sqlalchemy_utils/utils.py +sqlalchemy_utils/view.py sqlalchemy_utils/functions/__init__.py sqlalchemy_utils/functions/database.py sqlalchemy_utils/functions/foreign_keys.py @@ -99,13 +99,13 @@ tests/test_expressions.py tests/test_instant_defaults_listener.py tests/test_instrumented_list.py -tests/test_materialized_view.py tests/test_models.py tests/test_path.py tests/test_proxy_dict.py tests/test_query_chain.py tests/test_sort_query.py tests/test_translation_hybrid.py +tests/test_views.py tests/aggregate/__init__.py tests/aggregate/test_backrefs.py tests/aggregate/test_custom_select_expressions.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SQLAlchemy-Utils-0.33.5/sqlalchemy_utils/__init__.py new/SQLAlchemy-Utils-0.33.6/sqlalchemy_utils/__init__.py --- old/SQLAlchemy-Utils-0.33.5/sqlalchemy_utils/__init__.py 2018-09-20 09:38:10.000000000 +0200 +++ new/SQLAlchemy-Utils-0.33.6/sqlalchemy_utils/__init__.py 2018-10-14 09:09:03.000000000 +0200 @@ -53,10 +53,6 @@ force_auto_coercion, force_instant_defaults ) -from .materialized_view import ( # noqa - create_materialized_view, - refresh_materialized_view -) from .models import generic_repr, Timestamp # noqa from .observer import observes # noqa from .primitives import Country, Currency, Ltree, WeekDay, WeekDays # noqa @@ -98,5 +94,10 @@ UUIDType, WeekDaysType ) +from .view import ( # noqa + create_materialized_view, + create_view, + refresh_materialized_view +) -__version__ = '0.33.5' +__version__ = '0.33.6' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SQLAlchemy-Utils-0.33.5/sqlalchemy_utils/materialized_view.py new/SQLAlchemy-Utils-0.33.6/sqlalchemy_utils/materialized_view.py --- old/SQLAlchemy-Utils-0.33.5/sqlalchemy_utils/materialized_view.py 2018-02-18 15:30:37.000000000 +0100 +++ new/SQLAlchemy-Utils-0.33.6/sqlalchemy_utils/materialized_view.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,92 +0,0 @@ -import sqlalchemy as sa -from sqlalchemy.ext import compiler -from sqlalchemy.schema import DDLElement, PrimaryKeyConstraint - - -class CreateMaterializedView(DDLElement): - def __init__(self, name, selectable): - self.name = name - self.selectable = selectable - - -@compiler.compiles(CreateMaterializedView) -def compile_create_materialized_view(element, compiler, **kw): - return 'CREATE MATERIALIZED VIEW %s AS %s' % ( - element.name, - compiler.sql_compiler.process(element.selectable, literal_binds=True), - ) - - -class DropMateralizedView(DDLElement): - def __init__(self, name): - self.name = name - - -@compiler.compiles(DropMateralizedView) -def compile_drop_materialized_view(element, compiler, **kw): - return 'DROP MATERIALIZED VIEW IF EXISTS {} CASCADE'.format( - element.name - ) - - -def create_table_from_selectable( - name, - selectable, - indexes=None, - metadata=None -): - if indexes is None: - indexes = [] - if metadata is None: - metadata = sa.MetaData() - args = [ - sa.Column(c.name, c.type, primary_key=c.primary_key) - for c in selectable.c - ] + indexes - table = sa.Table(name, metadata, *args) - - if not any([c.primary_key for c in selectable.c]): - table.append_constraint( - PrimaryKeyConstraint(*[c.name for c in selectable.c]) - ) - return table - - -def create_materialized_view( - name, - selectable, - metadata, - indexes=None -): - table = create_table_from_selectable( - name=name, - selectable=selectable, - indexes=indexes, - metadata=None - ) - - sa.event.listen( - metadata, - 'after_create', - CreateMaterializedView(name, selectable) - ) - - @sa.event.listens_for(metadata, 'after_create') - def create_indexes(target, connection, **kw): - for idx in table.indexes: - idx.create(connection) - - sa.event.listen(metadata, 'before_drop', DropMateralizedView(name)) - return table - - -def refresh_materialized_view(session, name, concurrently=False): - # Since session.execute() bypasses autoflush, we must manually flush in - # order to include newly-created/modified objects in the refresh. - session.flush() - session.execute( - 'REFRESH MATERIALIZED VIEW {}{}'.format( - 'CONCURRENTLY ' if concurrently else '', - name - ) - ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SQLAlchemy-Utils-0.33.5/sqlalchemy_utils/types/password.py new/SQLAlchemy-Utils-0.33.6/sqlalchemy_utils/types/password.py --- old/SQLAlchemy-Utils-0.33.5/sqlalchemy_utils/types/password.py 2018-09-19 19:09:17.000000000 +0200 +++ new/SQLAlchemy-Utils-0.33.6/sqlalchemy_utils/types/password.py 2018-10-14 09:13:47.000000000 +0200 @@ -158,10 +158,17 @@ # Construct the passlib crypt context. self.context = LazyCryptContext(**kwargs) - self.hashing_method = 'hash' if hasattr(self, 'hash') else 'encrypt' self._max_length = max_length @property + def hashing_method(self): + return ( + 'hash' + if hasattr(self.context, 'hash') + else 'encrypt' + ) + + @property def length(self): """Get column length.""" if self._max_length is None: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SQLAlchemy-Utils-0.33.5/sqlalchemy_utils/view.py new/SQLAlchemy-Utils-0.33.6/sqlalchemy_utils/view.py --- old/SQLAlchemy-Utils-0.33.5/sqlalchemy_utils/view.py 1970-01-01 01:00:00.000000000 +0100 +++ new/SQLAlchemy-Utils-0.33.6/sqlalchemy_utils/view.py 2018-10-14 09:07:28.000000000 +0200 @@ -0,0 +1,122 @@ +import sqlalchemy as sa +from sqlalchemy.ext import compiler +from sqlalchemy.schema import DDLElement, PrimaryKeyConstraint + + +class CreateView(DDLElement): + def __init__(self, name, selectable, materialized=False): + self.name = name + self.selectable = selectable + self.materialized = materialized + + +@compiler.compiles(CreateView) +def compile_create_materialized_view(element, compiler, **kw): + return 'CREATE {}VIEW {} AS {}'.format( + 'MATERIALIZED ' if element.materialized else '', + element.name, + compiler.sql_compiler.process(element.selectable, literal_binds=True), + ) + + +class DropView(DDLElement): + def __init__(self, name, materialized=False): + self.name = name + self.materialized = materialized + + +@compiler.compiles(DropView) +def compile_drop_materialized_view(element, compiler, **kw): + return 'DROP {}VIEW IF EXISTS {} CASCADE'.format( + 'MATERIALIZED ' if element.materialized else '', + element.name + ) + + +def create_table_from_selectable( + name, + selectable, + indexes=None, + metadata=None +): + if indexes is None: + indexes = [] + if metadata is None: + metadata = sa.MetaData() + args = [ + sa.Column(c.name, c.type, primary_key=c.primary_key) + for c in selectable.c + ] + indexes + table = sa.Table(name, metadata, *args) + + if not any([c.primary_key for c in selectable.c]): + table.append_constraint( + PrimaryKeyConstraint(*[c.name for c in selectable.c]) + ) + return table + + +def create_materialized_view( + name, + selectable, + metadata, + indexes=None +): + table = create_table_from_selectable( + name=name, + selectable=selectable, + indexes=indexes, + metadata=None + ) + + sa.event.listen( + metadata, + 'after_create', + CreateView(name, selectable, materialized=True) + ) + + @sa.event.listens_for(metadata, 'after_create') + def create_indexes(target, connection, **kw): + for idx in table.indexes: + idx.create(connection) + + sa.event.listen( + metadata, + 'before_drop', + DropView(name, materialized=True) + ) + return table + + +def create_view( + name, + selectable, + metadata +): + table = create_table_from_selectable( + name=name, + selectable=selectable, + metadata=None + ) + + sa.event.listen(metadata, 'after_create', CreateView(name, selectable)) + + @sa.event.listens_for(metadata, 'after_create') + def create_indexes(target, connection, **kw): + for idx in table.indexes: + idx.create(connection) + + sa.event.listen(metadata, 'before_drop', DropView(name)) + return table + + +def refresh_materialized_view(session, name, concurrently=False): + # Since session.execute() bypasses autoflush, we must manually flush in + # order to include newly-created/modified objects in the refresh. + session.flush() + session.execute( + 'REFRESH MATERIALIZED VIEW {}{}'.format( + 'CONCURRENTLY ' if concurrently else '', + name + ) + ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SQLAlchemy-Utils-0.33.5/tests/test_materialized_view.py new/SQLAlchemy-Utils-0.33.6/tests/test_materialized_view.py --- old/SQLAlchemy-Utils-0.33.5/tests/test_materialized_view.py 2018-02-18 15:32:21.000000000 +0100 +++ new/SQLAlchemy-Utils-0.33.6/tests/test_materialized_view.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,76 +0,0 @@ -import pytest -import sqlalchemy as sa - -from sqlalchemy_utils import ( - create_materialized_view, - refresh_materialized_view -) - - -@pytest.fixture -def Article(Base, User): - class Article(Base): - __tablename__ = 'article' - id = sa.Column(sa.Integer, primary_key=True) - name = sa.Column(sa.String) - author_id = sa.Column(sa.Integer, sa.ForeignKey(User.id)) - author = sa.orm.relationship(User) - return Article - - -@pytest.fixture -def User(Base): - class User(Base): - __tablename__ = 'user' - id = sa.Column(sa.Integer, primary_key=True) - name = sa.Column(sa.String) - return User - - -@pytest.fixture -def ArticleMV(Base, Article, User): - class ArticleMV(Base): - __table__ = create_materialized_view( - name='article_mv', - selectable=sa.select( - [ - Article.id, - Article.name, - User.id.label('author_id'), - User.name.label('author_name') - ], - from_obj=( - Article.__table__ - .join(User, Article.author_id == User.id) - ) - ), - metadata=Base.metadata, - indexes=[sa.Index('article_mv_id_idx', 'id')] - ) - return ArticleMV - - -@pytest.fixture -def init_models(ArticleMV): - pass - - -@pytest.mark.usefixtures('postgresql_dsn') -class TestMaterializedViews: - def test_refresh_materialized_view( - self, - session, - Article, - User, - ArticleMV - ): - article = Article( - name='Some article', - author=User(name='Some user') - ) - session.add(article) - session.commit() - refresh_materialized_view(session, 'article_mv') - materialized = session.query(ArticleMV).first() - assert materialized.name == 'Some article' - assert materialized.author_name == 'Some user' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SQLAlchemy-Utils-0.33.5/tests/test_views.py new/SQLAlchemy-Utils-0.33.6/tests/test_views.py --- old/SQLAlchemy-Utils-0.33.5/tests/test_views.py 1970-01-01 01:00:00.000000000 +0100 +++ new/SQLAlchemy-Utils-0.33.6/tests/test_views.py 2018-10-14 09:07:28.000000000 +0200 @@ -0,0 +1,116 @@ +import pytest +import sqlalchemy as sa + +from sqlalchemy_utils import ( + create_materialized_view, + create_view, + refresh_materialized_view +) + + +@pytest.fixture +def Article(Base, User): + class Article(Base): + __tablename__ = 'article' + id = sa.Column(sa.Integer, primary_key=True) + name = sa.Column(sa.String) + author_id = sa.Column(sa.Integer, sa.ForeignKey(User.id)) + author = sa.orm.relationship(User) + return Article + + +@pytest.fixture +def User(Base): + class User(Base): + __tablename__ = 'user' + id = sa.Column(sa.Integer, primary_key=True) + name = sa.Column(sa.String) + return User + + +@pytest.fixture +def ArticleMV(Base, Article, User): + class ArticleMV(Base): + __table__ = create_materialized_view( + name='article_mv', + selectable=sa.select( + [ + Article.id, + Article.name, + User.id.label('author_id'), + User.name.label('author_name') + ], + from_obj=( + Article.__table__ + .join(User, Article.author_id == User.id) + ) + ), + metadata=Base.metadata, + indexes=[sa.Index('article_mv_id_idx', 'id')] + ) + return ArticleMV + + +@pytest.fixture +def ArticleView(Base, Article, User): + class ArticleView(Base): + __table__ = create_view( + name='article_view', + selectable=sa.select( + [ + Article.id, + Article.name, + User.id.label('author_id'), + User.name.label('author_name') + ], + from_obj=( + Article.__table__ + .join(User, Article.author_id == User.id) + ) + ), + metadata=Base.metadata + ) + return ArticleView + + +@pytest.fixture +def init_models(ArticleMV, ArticleView): + pass + + +@pytest.mark.usefixtures('postgresql_dsn') +class TestMaterializedViews: + def test_refresh_materialized_view( + self, + session, + Article, + User, + ArticleMV + ): + article = Article( + name='Some article', + author=User(name='Some user') + ) + session.add(article) + session.commit() + refresh_materialized_view(session, 'article_mv') + materialized = session.query(ArticleMV).first() + assert materialized.name == 'Some article' + assert materialized.author_name == 'Some user' + + def test_querying_view( + self, + session, + Article, + User, + ArticleView + ): + article = Article( + name='Some article', + author=User(name='Some user') + ) + session.add(article) + session.commit() + row = session.query(ArticleView).first() + assert row.name == 'Some article' + assert row.author_name == 'Some user'
participants (1)
-
root