SQLAlchemy-Utils 0.41.0__tar.gz → 0.41.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/CHANGES.rst +12 -0
- SQLAlchemy-Utils-0.41.2/PKG-INFO +96 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/README.rst +4 -4
- SQLAlchemy-Utils-0.41.2/SQLAlchemy_Utils.egg-info/PKG-INFO +96 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/SQLAlchemy_Utils.egg-info/SOURCES.txt +0 -1
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/SQLAlchemy_Utils.egg-info/not-zip-safe +1 -1
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/SQLAlchemy_Utils.egg-info/requires.txt +2 -2
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/docs/data_types.rst +11 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/docs/installation.rst +0 -1
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/docs/make.bat +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/setup.cfg +15 -15
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/setup.py +2 -3
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/__init__.py +1 -1
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/functions/database.py +1 -1
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/generic.py +18 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/encrypted/encrypted_type.py +17 -12
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/view.py +35 -10
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/aggregate/test_m2m.py +1 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/test_views.py +66 -9
- SQLAlchemy-Utils-0.41.0/PKG-INFO +0 -43
- SQLAlchemy-Utils-0.41.0/SQLAlchemy_Utils.egg-info/PKG-INFO +0 -43
- SQLAlchemy-Utils-0.41.0/tests/types/__pycache__/tmpgzyvpf7x +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/.isort.cfg +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/LICENSE +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/MANIFEST.in +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/SQLAlchemy_Utils.egg-info/dependency_links.txt +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/SQLAlchemy_Utils.egg-info/top_level.txt +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/conftest.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/docs/Makefile +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/docs/aggregates.rst +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/docs/conf.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/docs/database_helpers.rst +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/docs/foreign_key_helpers.rst +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/docs/generic_relationship.rst +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/docs/index.rst +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/docs/internationalization.rst +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/docs/license.rst +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/docs/listeners.rst +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/docs/models.rst +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/docs/observers.rst +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/docs/orm_helpers.rst +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/docs/range_data_types.rst +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/docs/testing.rst +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/docs/utility_classes.rst +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/docs/view.rst +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/aggregates.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/asserts.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/compat.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/exceptions.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/expressions.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/functions/__init__.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/functions/foreign_keys.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/functions/mock.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/functions/orm.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/functions/render.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/functions/sort_query.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/i18n.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/listeners.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/models.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/observer.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/operators.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/path.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/primitives/__init__.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/primitives/country.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/primitives/currency.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/primitives/ltree.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/primitives/weekday.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/primitives/weekdays.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/proxy_dict.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/query_chain.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/relationships/__init__.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/relationships/chained_join.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/__init__.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/arrow.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/bit.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/choice.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/color.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/country.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/currency.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/email.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/encrypted/__init__.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/encrypted/padding.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/enriched_datetime/__init__.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/enriched_datetime/arrow_datetime.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/enriched_datetime/enriched_date_type.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/enriched_datetime/enriched_datetime_type.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/enriched_datetime/pendulum_date.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/enriched_datetime/pendulum_datetime.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/ip_address.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/json.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/locale.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/ltree.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/password.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/pg_composite.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/phone_number.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/range.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/scalar_coercible.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/scalar_list.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/timezone.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/ts_vector.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/url.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/uuid.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/types/weekdays.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/sqlalchemy_utils/utils.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/__init__.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/aggregate/__init__.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/aggregate/test_backrefs.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/aggregate/test_custom_select_expressions.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/aggregate/test_join_table_inheritance.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/aggregate/test_m2m_m2m.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/aggregate/test_multiple_aggregates_per_class.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/aggregate/test_o2m_m2m.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/aggregate/test_o2m_o2m.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/aggregate/test_o2m_o2m_o2m.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/aggregate/test_search_vectors.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/aggregate/test_simple_paths.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/aggregate/test_with_column_alias.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/aggregate/test_with_ondelete_cascade.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/__init__.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/test_cast_if.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/test_database.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/test_dependent_objects.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/test_escape_like.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/test_get_bind.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/test_get_class_by_table.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/test_get_column_key.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/test_get_columns.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/test_get_hybrid_properties.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/test_get_mapper.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/test_get_primary_keys.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/test_get_referencing_foreign_keys.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/test_get_tables.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/test_get_type.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/test_getdotattr.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/test_has_changes.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/test_has_index.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/test_has_unique_index.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/test_identity.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/test_is_loaded.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/test_json_sql.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/test_jsonb_sql.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/test_make_order_by_deterministic.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/test_merge_references.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/test_naturally_equivalent.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/test_non_indexed_foreign_keys.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/test_quote.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/test_render.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/functions/test_table_name.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/generic_relationship/__init__.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/generic_relationship/test_abstract_base_class.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/generic_relationship/test_column_aliases.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/generic_relationship/test_composite_keys.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/generic_relationship/test_hybrid_properties.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/generic_relationship/test_single_table_inheritance.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/mixins.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/observes/__init__.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/observes/test_column_property.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/observes/test_dynamic_relationship.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/observes/test_m2m_m2m_m2m.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/observes/test_o2m_o2m_o2m.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/observes/test_o2m_o2o_o2m.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/observes/test_o2o_o2o.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/observes/test_o2o_o2o_o2o.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/primitives/__init__.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/primitives/test_country.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/primitives/test_currency.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/primitives/test_ltree.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/primitives/test_weekdays.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/relationships/__init__.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/relationships/test_chained_join.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/relationships/test_select_correlated_expression.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/test_asserts.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/test_auto_delete_orphans.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/test_case_insensitive_comparator.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/test_compat.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/test_expressions.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/test_instant_defaults_listener.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/test_instrumented_list.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/test_models.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/test_path.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/test_proxy_dict.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/test_query_chain.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/test_translation_hybrid.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/types/__init__.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/types/encrypted/test_padding.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/types/test_arrow.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/types/test_choice.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/types/test_color.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/types/test_composite.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/types/test_country.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/types/test_currency.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/types/test_date_range.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/types/test_datetime_range.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/types/test_email.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/types/test_encrypted.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/types/test_enriched_date_pendulum.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/types/test_enriched_datetime_arrow.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/types/test_enriched_datetime_pendulum.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/types/test_int_range.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/types/test_ip_address.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/types/test_json.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/types/test_locale.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/types/test_ltree.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/types/test_numeric_range.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/types/test_password.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/types/test_phonenumber.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/types/test_scalar_list.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/types/test_timezone.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/types/test_tsvector.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/types/test_url.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/types/test_uuid.py +0 -0
- {SQLAlchemy-Utils-0.41.0 → SQLAlchemy-Utils-0.41.2}/tests/types/test_weekdays.py +0 -0
|
@@ -3,6 +3,18 @@ Changelog
|
|
|
3
3
|
|
|
4
4
|
Here you can see the full list of changes between each SQLAlchemy-Utils release.
|
|
5
5
|
|
|
6
|
+
0.41.2 (2024-03-22)
|
|
7
|
+
^^^^^^^^^^^^^^^^^^^
|
|
8
|
+
|
|
9
|
+
- Fix breaking change introduced on SQLAlchemy 2.0.22 changes to `attributes.AttributeImpl` constructor (#733)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
0.41.1 (2023-04-27)
|
|
13
|
+
^^^^^^^^^^^^^^^^^^^
|
|
14
|
+
|
|
15
|
+
- Use a custom SQL construct for refreshing materialized views in
|
|
16
|
+
`refresh_materialized_view` (#703)
|
|
17
|
+
|
|
6
18
|
|
|
7
19
|
0.41.0 (2023-04-13)
|
|
8
20
|
^^^^^^^^^^^^^^^^^^^
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: SQLAlchemy-Utils
|
|
3
|
+
Version: 0.41.2
|
|
4
|
+
Summary: Various utility functions for SQLAlchemy.
|
|
5
|
+
Home-page: https://github.com/kvesteri/sqlalchemy-utils
|
|
6
|
+
Author: Konsta Vesterinen, Ryan Leckey, Janne Vanhala, Vesa Uimonen
|
|
7
|
+
Author-email: konsta@fastmonkeys.com
|
|
8
|
+
License: BSD
|
|
9
|
+
Platform: any
|
|
10
|
+
Classifier: Environment :: Web Environment
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
|
22
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
|
+
Requires-Python: >=3.7
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: SQLAlchemy>=1.3
|
|
26
|
+
Requires-Dist: importlib_metadata; python_version < "3.8"
|
|
27
|
+
Provides-Extra: test
|
|
28
|
+
Requires-Dist: pytest==7.4.4; extra == "test"
|
|
29
|
+
Requires-Dist: Pygments>=1.2; extra == "test"
|
|
30
|
+
Requires-Dist: Jinja2>=2.3; extra == "test"
|
|
31
|
+
Requires-Dist: docutils>=0.10; extra == "test"
|
|
32
|
+
Requires-Dist: flexmock>=0.9.7; extra == "test"
|
|
33
|
+
Requires-Dist: psycopg>=3.1.8; extra == "test"
|
|
34
|
+
Requires-Dist: psycopg2>=2.5.1; extra == "test"
|
|
35
|
+
Requires-Dist: psycopg2cffi>=2.8.1; extra == "test"
|
|
36
|
+
Requires-Dist: pg8000>=1.12.4; extra == "test"
|
|
37
|
+
Requires-Dist: pytz>=2014.2; extra == "test"
|
|
38
|
+
Requires-Dist: python-dateutil>=2.6; extra == "test"
|
|
39
|
+
Requires-Dist: backports.zoneinfo; python_version < "3.9" and extra == "test"
|
|
40
|
+
Requires-Dist: pymysql; extra == "test"
|
|
41
|
+
Requires-Dist: flake8>=2.4.0; extra == "test"
|
|
42
|
+
Requires-Dist: isort>=4.2.2; extra == "test"
|
|
43
|
+
Requires-Dist: pyodbc; extra == "test"
|
|
44
|
+
Provides-Extra: babel
|
|
45
|
+
Requires-Dist: Babel>=1.3; extra == "babel"
|
|
46
|
+
Provides-Extra: arrow
|
|
47
|
+
Requires-Dist: arrow>=0.3.4; extra == "arrow"
|
|
48
|
+
Provides-Extra: pendulum
|
|
49
|
+
Requires-Dist: pendulum>=2.0.5; extra == "pendulum"
|
|
50
|
+
Provides-Extra: intervals
|
|
51
|
+
Requires-Dist: intervals>=0.7.1; extra == "intervals"
|
|
52
|
+
Provides-Extra: phone
|
|
53
|
+
Requires-Dist: phonenumbers>=5.9.2; extra == "phone"
|
|
54
|
+
Provides-Extra: password
|
|
55
|
+
Requires-Dist: passlib<2.0,>=1.6; extra == "password"
|
|
56
|
+
Provides-Extra: color
|
|
57
|
+
Requires-Dist: colour>=0.0.4; extra == "color"
|
|
58
|
+
Provides-Extra: timezone
|
|
59
|
+
Requires-Dist: python-dateutil; extra == "timezone"
|
|
60
|
+
Provides-Extra: url
|
|
61
|
+
Requires-Dist: furl>=0.4.1; extra == "url"
|
|
62
|
+
Provides-Extra: encrypted
|
|
63
|
+
Requires-Dist: cryptography>=0.6; extra == "encrypted"
|
|
64
|
+
Provides-Extra: test-all
|
|
65
|
+
Requires-Dist: Babel>=1.3; extra == "test-all"
|
|
66
|
+
Requires-Dist: Jinja2>=2.3; extra == "test-all"
|
|
67
|
+
Requires-Dist: Pygments>=1.2; extra == "test-all"
|
|
68
|
+
Requires-Dist: arrow>=0.3.4; extra == "test-all"
|
|
69
|
+
Requires-Dist: backports.zoneinfo; python_version < "3.9" and extra == "test-all"
|
|
70
|
+
Requires-Dist: colour>=0.0.4; extra == "test-all"
|
|
71
|
+
Requires-Dist: cryptography>=0.6; extra == "test-all"
|
|
72
|
+
Requires-Dist: docutils>=0.10; extra == "test-all"
|
|
73
|
+
Requires-Dist: flake8>=2.4.0; extra == "test-all"
|
|
74
|
+
Requires-Dist: flexmock>=0.9.7; extra == "test-all"
|
|
75
|
+
Requires-Dist: furl>=0.4.1; extra == "test-all"
|
|
76
|
+
Requires-Dist: intervals>=0.7.1; extra == "test-all"
|
|
77
|
+
Requires-Dist: isort>=4.2.2; extra == "test-all"
|
|
78
|
+
Requires-Dist: passlib<2.0,>=1.6; extra == "test-all"
|
|
79
|
+
Requires-Dist: pendulum>=2.0.5; extra == "test-all"
|
|
80
|
+
Requires-Dist: pg8000>=1.12.4; extra == "test-all"
|
|
81
|
+
Requires-Dist: phonenumbers>=5.9.2; extra == "test-all"
|
|
82
|
+
Requires-Dist: psycopg2>=2.5.1; extra == "test-all"
|
|
83
|
+
Requires-Dist: psycopg2cffi>=2.8.1; extra == "test-all"
|
|
84
|
+
Requires-Dist: psycopg>=3.1.8; extra == "test-all"
|
|
85
|
+
Requires-Dist: pymysql; extra == "test-all"
|
|
86
|
+
Requires-Dist: pyodbc; extra == "test-all"
|
|
87
|
+
Requires-Dist: pytest==7.4.4; extra == "test-all"
|
|
88
|
+
Requires-Dist: python-dateutil; extra == "test-all"
|
|
89
|
+
Requires-Dist: python-dateutil>=2.6; extra == "test-all"
|
|
90
|
+
Requires-Dist: pytz>=2014.2; extra == "test-all"
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
SQLAlchemy-Utils
|
|
94
|
+
----------------
|
|
95
|
+
|
|
96
|
+
Various utility functions and custom data types for SQLAlchemy.
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
SQLAlchemy-Utils
|
|
2
2
|
================
|
|
3
3
|
|
|
4
|
-
|Build
|
|
5
|
-
|
|
4
|
+
|Build| |Version Status| |Downloads|
|
|
6
5
|
|
|
7
6
|
Various utility functions, new data types and helpers for SQLAlchemy.
|
|
8
7
|
|
|
@@ -14,8 +13,9 @@ Resources
|
|
|
14
13
|
- `Issue Tracker <https://github.com/kvesteri/sqlalchemy-utils/issues>`_
|
|
15
14
|
- `Code <https://github.com/kvesteri/sqlalchemy-utils/>`_
|
|
16
15
|
|
|
17
|
-
.. |Build
|
|
18
|
-
:target: https://
|
|
16
|
+
.. |Build| image:: https://github.com/kvesteri/sqlalchemy-utils/actions/workflows/test.yaml/badge.svg?branch=master
|
|
17
|
+
:target: https://github.com/kvesteri/sqlalchemy-utils/actions/workflows/test.yaml
|
|
18
|
+
:alt: Tests
|
|
19
19
|
.. |Version Status| image:: https://img.shields.io/pypi/v/SQLAlchemy-Utils.svg
|
|
20
20
|
:target: https://pypi.python.org/pypi/SQLAlchemy-Utils/
|
|
21
21
|
.. |Downloads| image:: https://img.shields.io/pypi/dm/SQLAlchemy-Utils.svg
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: SQLAlchemy-Utils
|
|
3
|
+
Version: 0.41.2
|
|
4
|
+
Summary: Various utility functions for SQLAlchemy.
|
|
5
|
+
Home-page: https://github.com/kvesteri/sqlalchemy-utils
|
|
6
|
+
Author: Konsta Vesterinen, Ryan Leckey, Janne Vanhala, Vesa Uimonen
|
|
7
|
+
Author-email: konsta@fastmonkeys.com
|
|
8
|
+
License: BSD
|
|
9
|
+
Platform: any
|
|
10
|
+
Classifier: Environment :: Web Environment
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
|
22
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
|
+
Requires-Python: >=3.7
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: SQLAlchemy>=1.3
|
|
26
|
+
Requires-Dist: importlib_metadata; python_version < "3.8"
|
|
27
|
+
Provides-Extra: test
|
|
28
|
+
Requires-Dist: pytest==7.4.4; extra == "test"
|
|
29
|
+
Requires-Dist: Pygments>=1.2; extra == "test"
|
|
30
|
+
Requires-Dist: Jinja2>=2.3; extra == "test"
|
|
31
|
+
Requires-Dist: docutils>=0.10; extra == "test"
|
|
32
|
+
Requires-Dist: flexmock>=0.9.7; extra == "test"
|
|
33
|
+
Requires-Dist: psycopg>=3.1.8; extra == "test"
|
|
34
|
+
Requires-Dist: psycopg2>=2.5.1; extra == "test"
|
|
35
|
+
Requires-Dist: psycopg2cffi>=2.8.1; extra == "test"
|
|
36
|
+
Requires-Dist: pg8000>=1.12.4; extra == "test"
|
|
37
|
+
Requires-Dist: pytz>=2014.2; extra == "test"
|
|
38
|
+
Requires-Dist: python-dateutil>=2.6; extra == "test"
|
|
39
|
+
Requires-Dist: backports.zoneinfo; python_version < "3.9" and extra == "test"
|
|
40
|
+
Requires-Dist: pymysql; extra == "test"
|
|
41
|
+
Requires-Dist: flake8>=2.4.0; extra == "test"
|
|
42
|
+
Requires-Dist: isort>=4.2.2; extra == "test"
|
|
43
|
+
Requires-Dist: pyodbc; extra == "test"
|
|
44
|
+
Provides-Extra: babel
|
|
45
|
+
Requires-Dist: Babel>=1.3; extra == "babel"
|
|
46
|
+
Provides-Extra: arrow
|
|
47
|
+
Requires-Dist: arrow>=0.3.4; extra == "arrow"
|
|
48
|
+
Provides-Extra: pendulum
|
|
49
|
+
Requires-Dist: pendulum>=2.0.5; extra == "pendulum"
|
|
50
|
+
Provides-Extra: intervals
|
|
51
|
+
Requires-Dist: intervals>=0.7.1; extra == "intervals"
|
|
52
|
+
Provides-Extra: phone
|
|
53
|
+
Requires-Dist: phonenumbers>=5.9.2; extra == "phone"
|
|
54
|
+
Provides-Extra: password
|
|
55
|
+
Requires-Dist: passlib<2.0,>=1.6; extra == "password"
|
|
56
|
+
Provides-Extra: color
|
|
57
|
+
Requires-Dist: colour>=0.0.4; extra == "color"
|
|
58
|
+
Provides-Extra: timezone
|
|
59
|
+
Requires-Dist: python-dateutil; extra == "timezone"
|
|
60
|
+
Provides-Extra: url
|
|
61
|
+
Requires-Dist: furl>=0.4.1; extra == "url"
|
|
62
|
+
Provides-Extra: encrypted
|
|
63
|
+
Requires-Dist: cryptography>=0.6; extra == "encrypted"
|
|
64
|
+
Provides-Extra: test-all
|
|
65
|
+
Requires-Dist: Babel>=1.3; extra == "test-all"
|
|
66
|
+
Requires-Dist: Jinja2>=2.3; extra == "test-all"
|
|
67
|
+
Requires-Dist: Pygments>=1.2; extra == "test-all"
|
|
68
|
+
Requires-Dist: arrow>=0.3.4; extra == "test-all"
|
|
69
|
+
Requires-Dist: backports.zoneinfo; python_version < "3.9" and extra == "test-all"
|
|
70
|
+
Requires-Dist: colour>=0.0.4; extra == "test-all"
|
|
71
|
+
Requires-Dist: cryptography>=0.6; extra == "test-all"
|
|
72
|
+
Requires-Dist: docutils>=0.10; extra == "test-all"
|
|
73
|
+
Requires-Dist: flake8>=2.4.0; extra == "test-all"
|
|
74
|
+
Requires-Dist: flexmock>=0.9.7; extra == "test-all"
|
|
75
|
+
Requires-Dist: furl>=0.4.1; extra == "test-all"
|
|
76
|
+
Requires-Dist: intervals>=0.7.1; extra == "test-all"
|
|
77
|
+
Requires-Dist: isort>=4.2.2; extra == "test-all"
|
|
78
|
+
Requires-Dist: passlib<2.0,>=1.6; extra == "test-all"
|
|
79
|
+
Requires-Dist: pendulum>=2.0.5; extra == "test-all"
|
|
80
|
+
Requires-Dist: pg8000>=1.12.4; extra == "test-all"
|
|
81
|
+
Requires-Dist: phonenumbers>=5.9.2; extra == "test-all"
|
|
82
|
+
Requires-Dist: psycopg2>=2.5.1; extra == "test-all"
|
|
83
|
+
Requires-Dist: psycopg2cffi>=2.8.1; extra == "test-all"
|
|
84
|
+
Requires-Dist: psycopg>=3.1.8; extra == "test-all"
|
|
85
|
+
Requires-Dist: pymysql; extra == "test-all"
|
|
86
|
+
Requires-Dist: pyodbc; extra == "test-all"
|
|
87
|
+
Requires-Dist: pytest==7.4.4; extra == "test-all"
|
|
88
|
+
Requires-Dist: python-dateutil; extra == "test-all"
|
|
89
|
+
Requires-Dist: python-dateutil>=2.6; extra == "test-all"
|
|
90
|
+
Requires-Dist: pytz>=2014.2; extra == "test-all"
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
SQLAlchemy-Utils
|
|
94
|
+
----------------
|
|
95
|
+
|
|
96
|
+
Various utility functions and custom data types for SQLAlchemy.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
@@ -28,7 +28,7 @@ pendulum>=2.0.5
|
|
|
28
28
|
phonenumbers>=5.9.2
|
|
29
29
|
|
|
30
30
|
[test]
|
|
31
|
-
pytest
|
|
31
|
+
pytest==7.4.4
|
|
32
32
|
Pygments>=1.2
|
|
33
33
|
Jinja2>=2.3
|
|
34
34
|
docutils>=0.10
|
|
@@ -69,7 +69,7 @@ psycopg2cffi>=2.8.1
|
|
|
69
69
|
psycopg>=3.1.8
|
|
70
70
|
pymysql
|
|
71
71
|
pyodbc
|
|
72
|
-
pytest
|
|
72
|
+
pytest==7.4.4
|
|
73
73
|
python-dateutil
|
|
74
74
|
python-dateutil>=2.6
|
|
75
75
|
pytz>=2014.2
|
|
@@ -76,6 +76,9 @@ EncryptedType
|
|
|
76
76
|
|
|
77
77
|
.. module:: sqlalchemy_utils.types.encrypted.encrypted_type
|
|
78
78
|
|
|
79
|
+
.. deprecated:: 0.36.6
|
|
80
|
+
Use StringEncryptedType instead
|
|
81
|
+
|
|
79
82
|
.. autoclass:: EncryptedType
|
|
80
83
|
|
|
81
84
|
JSONType
|
|
@@ -142,6 +145,14 @@ ScalarListType
|
|
|
142
145
|
.. autoclass:: ScalarListType
|
|
143
146
|
|
|
144
147
|
|
|
148
|
+
StringEncryptedType
|
|
149
|
+
-------------------
|
|
150
|
+
|
|
151
|
+
.. module:: sqlalchemy_utils.types.encrypted.encrypted_type
|
|
152
|
+
|
|
153
|
+
.. autoclass:: StringEncryptedType
|
|
154
|
+
|
|
155
|
+
|
|
145
156
|
TimezoneType
|
|
146
157
|
------------
|
|
147
158
|
|
|
File without changes
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
[flake8]
|
|
2
|
-
max-line-length = 88
|
|
3
|
-
extend-ignore = E203
|
|
4
|
-
exclude =
|
|
5
|
-
.eggs
|
|
6
|
-
.git
|
|
7
|
-
.tox
|
|
8
|
-
.venv
|
|
9
|
-
build
|
|
10
|
-
docs/conf.py
|
|
11
|
-
|
|
12
|
-
[egg_info]
|
|
13
|
-
tag_build =
|
|
14
|
-
tag_date = 0
|
|
15
|
-
|
|
1
|
+
[flake8]
|
|
2
|
+
max-line-length = 88
|
|
3
|
+
extend-ignore = E203
|
|
4
|
+
exclude =
|
|
5
|
+
.eggs
|
|
6
|
+
.git
|
|
7
|
+
.tox
|
|
8
|
+
.venv
|
|
9
|
+
build
|
|
10
|
+
docs/conf.py
|
|
11
|
+
|
|
12
|
+
[egg_info]
|
|
13
|
+
tag_build =
|
|
14
|
+
tag_date = 0
|
|
15
|
+
|
|
@@ -22,7 +22,7 @@ def get_version():
|
|
|
22
22
|
|
|
23
23
|
extras_require = {
|
|
24
24
|
'test': [
|
|
25
|
-
'pytest
|
|
25
|
+
'pytest==7.4.4',
|
|
26
26
|
'Pygments>=1.2',
|
|
27
27
|
'Jinja2>=2.3',
|
|
28
28
|
'docutils>=0.10',
|
|
@@ -79,7 +79,7 @@ setup(
|
|
|
79
79
|
"importlib_metadata ; python_version<'3.8'",
|
|
80
80
|
],
|
|
81
81
|
extras_require=extras_require,
|
|
82
|
-
python_requires='>=3.
|
|
82
|
+
python_requires='>=3.7',
|
|
83
83
|
classifiers=[
|
|
84
84
|
'Environment :: Web Environment',
|
|
85
85
|
'Intended Audience :: Developers',
|
|
@@ -87,7 +87,6 @@ setup(
|
|
|
87
87
|
'Operating System :: OS Independent',
|
|
88
88
|
'Programming Language :: Python',
|
|
89
89
|
'Programming Language :: Python :: 3',
|
|
90
|
-
'Programming Language :: Python :: 3.6',
|
|
91
90
|
'Programming Language :: Python :: 3.7',
|
|
92
91
|
'Programming Language :: Python :: 3.8',
|
|
93
92
|
'Programming Language :: Python :: 3.9',
|
|
@@ -13,6 +13,24 @@ from .functions.orm import _get_class_registry
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class GenericAttributeImpl(attributes.ScalarAttributeImpl):
|
|
16
|
+
def __init__(self, *args, **kwargs):
|
|
17
|
+
"""
|
|
18
|
+
The constructor of attributes.AttributeImpl changed in SQLAlchemy 2.0.22,
|
|
19
|
+
adding a 'default_function' required positional argument before 'dispatch'.
|
|
20
|
+
This adjustment ensures compatibility across versions by inserting None for
|
|
21
|
+
'default_function' in versions >= 2.0.22.
|
|
22
|
+
|
|
23
|
+
Arguments received: (class, key, dispatch)
|
|
24
|
+
Required by AttributeImpl: (class, key, default_function, dispatch)
|
|
25
|
+
Setting None as default_function here.
|
|
26
|
+
"""
|
|
27
|
+
# Adjust for SQLAlchemy version change
|
|
28
|
+
sqlalchemy_version = tuple(map(int, sa.__version__.split('.')))
|
|
29
|
+
if sqlalchemy_version >= (2, 0, 22):
|
|
30
|
+
args = (*args[:2], None, *args[2:])
|
|
31
|
+
|
|
32
|
+
super().__init__(*args, **kwargs)
|
|
33
|
+
|
|
16
34
|
def get(self, state, dict_, passive=attributes.PASSIVE_OFF):
|
|
17
35
|
if self.key in dict_:
|
|
18
36
|
return dict_[self.key]
|
|
@@ -223,15 +223,15 @@ class FernetEngine(EncryptionDecryptionBaseEngine):
|
|
|
223
223
|
|
|
224
224
|
class StringEncryptedType(TypeDecorator, ScalarCoercible):
|
|
225
225
|
"""
|
|
226
|
-
|
|
226
|
+
StringEncryptedType provides a way to encrypt and decrypt values,
|
|
227
227
|
to and from databases, that their type is a basic SQLAlchemy type.
|
|
228
228
|
For example Unicode, String or even Boolean.
|
|
229
229
|
On the way in, the value is encrypted and on the way out the stored value
|
|
230
230
|
is decrypted.
|
|
231
231
|
|
|
232
|
-
|
|
232
|
+
StringEncryptedType needs Cryptography_ library in order to work.
|
|
233
233
|
|
|
234
|
-
When declaring a column which will be of type
|
|
234
|
+
When declaring a column which will be of type StringEncryptedType
|
|
235
235
|
it is better to be as precise as possible and follow the pattern
|
|
236
236
|
below.
|
|
237
237
|
|
|
@@ -240,11 +240,11 @@ class StringEncryptedType(TypeDecorator, ScalarCoercible):
|
|
|
240
240
|
::
|
|
241
241
|
|
|
242
242
|
|
|
243
|
-
a_column = sa.Column(
|
|
243
|
+
a_column = sa.Column(StringEncryptedType(sa.Unicode,
|
|
244
244
|
secret_key,
|
|
245
245
|
FernetEngine))
|
|
246
246
|
|
|
247
|
-
another_column = sa.Column(
|
|
247
|
+
another_column = sa.Column(StringEncryptedType(sa.Unicode,
|
|
248
248
|
secret_key,
|
|
249
249
|
AesEngine,
|
|
250
250
|
'pkcs5'))
|
|
@@ -264,7 +264,7 @@ class StringEncryptedType(TypeDecorator, ScalarCoercible):
|
|
|
264
264
|
from sqlalchemy.ext.declarative import declarative_base
|
|
265
265
|
from sqlalchemy.orm import sessionmaker
|
|
266
266
|
|
|
267
|
-
from sqlalchemy_utils import
|
|
267
|
+
from sqlalchemy_utils import StringEncryptedType
|
|
268
268
|
from sqlalchemy_utils.types.encrypted.encrypted_type import AesEngine
|
|
269
269
|
|
|
270
270
|
secret_key = 'secretkey1234'
|
|
@@ -277,19 +277,19 @@ class StringEncryptedType(TypeDecorator, ScalarCoercible):
|
|
|
277
277
|
class User(Base):
|
|
278
278
|
__tablename__ = "user"
|
|
279
279
|
id = sa.Column(sa.Integer, primary_key=True)
|
|
280
|
-
username = sa.Column(
|
|
280
|
+
username = sa.Column(StringEncryptedType(sa.Unicode,
|
|
281
281
|
secret_key,
|
|
282
282
|
AesEngine,
|
|
283
283
|
'pkcs5'))
|
|
284
|
-
access_token = sa.Column(
|
|
284
|
+
access_token = sa.Column(StringEncryptedType(sa.String,
|
|
285
285
|
secret_key,
|
|
286
286
|
AesEngine,
|
|
287
287
|
'pkcs5'))
|
|
288
|
-
is_active = sa.Column(
|
|
288
|
+
is_active = sa.Column(StringEncryptedType(sa.Boolean,
|
|
289
289
|
secret_key,
|
|
290
290
|
AesEngine,
|
|
291
291
|
'zeroes'))
|
|
292
|
-
number_of_accounts = sa.Column(
|
|
292
|
+
number_of_accounts = sa.Column(StringEncryptedType(sa.Integer,
|
|
293
293
|
secret_key,
|
|
294
294
|
AesEngine,
|
|
295
295
|
'oneandzeroes'))
|
|
@@ -345,7 +345,7 @@ class StringEncryptedType(TypeDecorator, ScalarCoercible):
|
|
|
345
345
|
class User(Base):
|
|
346
346
|
__tablename__ = 'user'
|
|
347
347
|
id = sa.Column(sa.Integer, primary_key=True)
|
|
348
|
-
username = sa.Column(
|
|
348
|
+
username = sa.Column(StringEncryptedType(
|
|
349
349
|
sa.Unicode, get_key))
|
|
350
350
|
|
|
351
351
|
"""
|
|
@@ -363,7 +363,7 @@ class StringEncryptedType(TypeDecorator, ScalarCoercible):
|
|
|
363
363
|
"""Initialization."""
|
|
364
364
|
if not cryptography:
|
|
365
365
|
raise ImproperlyConfigured(
|
|
366
|
-
"'cryptography' is required to use
|
|
366
|
+
"'cryptography' is required to use StringEncryptedType"
|
|
367
367
|
)
|
|
368
368
|
super().__init__(**kwargs)
|
|
369
369
|
# set the underlying type
|
|
@@ -457,6 +457,11 @@ class StringEncryptedType(TypeDecorator, ScalarCoercible):
|
|
|
457
457
|
|
|
458
458
|
|
|
459
459
|
class EncryptedType(StringEncryptedType):
|
|
460
|
+
"""
|
|
461
|
+
The 'EncryptedType' class will change implementation from
|
|
462
|
+
'LargeBinary' to 'String' in a future version. Use
|
|
463
|
+
'StringEncryptedType' to use the 'String' implementation.
|
|
464
|
+
"""
|
|
460
465
|
impl = LargeBinary
|
|
461
466
|
|
|
462
467
|
def __init__(self, *args, **kwargs):
|
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
import sqlalchemy as sa
|
|
2
2
|
from sqlalchemy.ext import compiler
|
|
3
3
|
from sqlalchemy.schema import DDLElement, PrimaryKeyConstraint
|
|
4
|
+
from sqlalchemy.sql.expression import ClauseElement, Executable
|
|
4
5
|
|
|
5
6
|
from sqlalchemy_utils.functions import get_columns
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
class CreateView(DDLElement):
|
|
9
|
-
def __init__(self, name, selectable, materialized=False):
|
|
10
|
+
def __init__(self, name, selectable, materialized=False, replace=False):
|
|
11
|
+
if materialized and replace:
|
|
12
|
+
raise ValueError("Cannot use CREATE OR REPLACE with materialized views")
|
|
10
13
|
self.name = name
|
|
11
14
|
self.selectable = selectable
|
|
12
15
|
self.materialized = materialized
|
|
16
|
+
self.replace = replace
|
|
13
17
|
|
|
14
18
|
|
|
15
19
|
@compiler.compiles(CreateView)
|
|
16
20
|
def compile_create_materialized_view(element, compiler, **kw):
|
|
17
|
-
return 'CREATE {}VIEW {} AS {}'.format(
|
|
21
|
+
return 'CREATE {}{}VIEW {} AS {}'.format(
|
|
22
|
+
'OR REPLACE ' if element.replace else '',
|
|
18
23
|
'MATERIALIZED ' if element.materialized else '',
|
|
19
24
|
compiler.dialect.identifier_preparer.quote(element.name),
|
|
20
25
|
compiler.sql_compiler.process(element.selectable, literal_binds=True),
|
|
@@ -123,7 +128,8 @@ def create_view(
|
|
|
123
128
|
name,
|
|
124
129
|
selectable,
|
|
125
130
|
metadata,
|
|
126
|
-
cascade_on_drop=True
|
|
131
|
+
cascade_on_drop=True,
|
|
132
|
+
replace=False,
|
|
127
133
|
):
|
|
128
134
|
""" Create a view on a given metadata
|
|
129
135
|
|
|
@@ -132,6 +138,10 @@ def create_view(
|
|
|
132
138
|
:param metadata:
|
|
133
139
|
An SQLAlchemy Metadata instance that stores the features of the
|
|
134
140
|
database being described.
|
|
141
|
+
:param cascade_on_drop: If ``True`` the view will be dropped with
|
|
142
|
+
``CASCADE``, deleting all dependent objects as well.
|
|
143
|
+
:param replace: If ``True`` the view will be created with ``OR REPLACE``,
|
|
144
|
+
replacing an existing view with the same name.
|
|
135
145
|
|
|
136
146
|
The process for creating a view is similar to the standard way that a
|
|
137
147
|
table is constructed, except that a selectable is provided instead of
|
|
@@ -163,7 +173,11 @@ def create_view(
|
|
|
163
173
|
metadata=None
|
|
164
174
|
)
|
|
165
175
|
|
|
166
|
-
sa.event.listen(
|
|
176
|
+
sa.event.listen(
|
|
177
|
+
metadata,
|
|
178
|
+
'after_create',
|
|
179
|
+
CreateView(name, selectable, replace=replace),
|
|
180
|
+
)
|
|
167
181
|
|
|
168
182
|
@sa.event.listens_for(metadata, 'after_create')
|
|
169
183
|
def create_indexes(target, connection, **kw):
|
|
@@ -178,6 +192,22 @@ def create_view(
|
|
|
178
192
|
return table
|
|
179
193
|
|
|
180
194
|
|
|
195
|
+
class RefreshMaterializedView(Executable, ClauseElement):
|
|
196
|
+
inherit_cache = True
|
|
197
|
+
|
|
198
|
+
def __init__(self, name, concurrently):
|
|
199
|
+
self.name = name
|
|
200
|
+
self.concurrently = concurrently
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
@compiler.compiles(RefreshMaterializedView)
|
|
204
|
+
def compile_refresh_materialized_view(element, compiler):
|
|
205
|
+
return 'REFRESH MATERIALIZED VIEW {concurrently}{name}'.format(
|
|
206
|
+
concurrently='CONCURRENTLY ' if element.concurrently else '',
|
|
207
|
+
name=compiler.dialect.identifier_preparer.quote(element.name),
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
|
|
181
211
|
def refresh_materialized_view(session, name, concurrently=False):
|
|
182
212
|
""" Refreshes an already existing materialized view
|
|
183
213
|
|
|
@@ -190,9 +220,4 @@ def refresh_materialized_view(session, name, concurrently=False):
|
|
|
190
220
|
# Since session.execute() bypasses autoflush, we must manually flush in
|
|
191
221
|
# order to include newly-created/modified objects in the refresh.
|
|
192
222
|
session.flush()
|
|
193
|
-
session.execute(
|
|
194
|
-
sa.text('REFRESH MATERIALIZED VIEW {}{}'.format(
|
|
195
|
-
'CONCURRENTLY ' if concurrently else '',
|
|
196
|
-
session.bind.engine.dialect.identifier_preparer.quote(name)
|
|
197
|
-
))
|
|
198
|
-
)
|
|
223
|
+
session.execute(RefreshMaterializedView(name, concurrently))
|