diff --git a/.github/workflows/tests.yml b/.github/workflows/tests1.yml similarity index 74% rename from .github/workflows/tests.yml rename to .github/workflows/tests1.yml index 66c7948..5354812 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests1.yml @@ -1,11 +1,11 @@ -name: Tests +name: Tests I on: pull_request: paths: - '**.py' - '!setup.py' - - '.github/workflows/tests.yml' + - '.github/workflows/tests1.yml' jobs: django-tests: @@ -18,7 +18,7 @@ jobs: uses: actions/checkout@v4 with: repository: 'timgraham/django' - ref: 'snowflake-6.0.x' + ref: 'snowflake-6.1.x' path: 'django_repo' - name: Install system packages for Django's Python test dependencies run: | @@ -37,27 +37,16 @@ jobs: - name: Run the tests run: > python3 django_repo/tests/runtests.py --settings snowflake_settings -v 2 + admin_changelist + admin_custom_urls + admin_docs + admin_filters + admin_inlines + admin_ordering + admin_utils + admin_views aggregation aggregation_regress - annotations - backends - basic - bulk_create - composite_pk - dates - datetimes - db_functions - expressions - expressions_window - field_defaults - inspectdb - introspection - lookup - migrations - model_fields - queries - schema - timezones env: SNOWFLAKE_ACCOUNT: ${{ secrets.SNOWFLAKE_ACCOUNT }} SNOWFLAKE_PASSWORD: ${{ secrets.SNOWFLAKE_PASSWORD }} diff --git a/.github/workflows/tests2.yml b/.github/workflows/tests2.yml new file mode 100644 index 0000000..74d6c70 --- /dev/null +++ b/.github/workflows/tests2.yml @@ -0,0 +1,73 @@ +name: Tests II + +on: + pull_request: + paths: + - '**.py' + - '!setup.py' + - '.github/workflows/tests2.yml' + +jobs: + django-tests: + runs-on: ubuntu-latest + name: Django Test Suite + steps: + - name: Checkout django-snowflake + uses: actions/checkout@v4 + - name: Checkout Django + uses: actions/checkout@v4 + with: + repository: 'timgraham/django' + ref: 'snowflake-6.1.x' + path: 'django_repo' + - name: Install system packages for Django's Python test dependencies + run: | + sudo apt-get update + sudo apt-get install libmemcached-dev + - name: Install Django and its Python test dependencies + run: | + pip3 install -U pip + cd django_repo/tests/ + pip3 install -e .. + pip3 install -r requirements/py3.txt + - name: install the django-snowflake backend + run: pip3 install . + - name: Copy the test settings file + run: cp .github/workflows/snowflake_settings.py django_repo/tests/ + - name: Run the tests + run: > + python3 django_repo/tests/runtests.py --settings snowflake_settings -v 2 + annotations + auth_tests + basic + bulk_create + cache + check_framework + composite_pk + constraints + contenttypes_tests + custom_columns + custom_lookups + custom_managers + custom_methods + custom_pk + datatypes + dates + datetimes + db_functions + db_typecasts + db_utils + defer + defer_regress + delete + delete_regress + empty + expressions + expressions_case + expressions_window + extra_regress + env: + SNOWFLAKE_ACCOUNT: ${{ secrets.SNOWFLAKE_ACCOUNT }} + SNOWFLAKE_PASSWORD: ${{ secrets.SNOWFLAKE_PASSWORD }} + SNOWFLAKE_USER: ${{ secrets.SNOWFLAKE_USER }} + SNOWFLAKE_WAREHOUSE: ${{ secrets.SNOWFLAKE_WAREHOUSE }} diff --git a/.github/workflows/tests3.yml b/.github/workflows/tests3.yml new file mode 100644 index 0000000..57c4366 --- /dev/null +++ b/.github/workflows/tests3.yml @@ -0,0 +1,92 @@ +name: Tests III + +on: + pull_request: + paths: + - '**.py' + - '!setup.py' + - '.github/workflows/tests3.yml' + +jobs: + django-tests: + runs-on: ubuntu-latest + name: Django Test Suite + steps: + - name: Checkout django-snowflake + uses: actions/checkout@v4 + - name: Checkout Django + uses: actions/checkout@v4 + with: + repository: 'timgraham/django' + ref: 'snowflake-6.1.x' + path: 'django_repo' + - name: Install system packages for Django's Python test dependencies + run: | + sudo apt-get update + sudo apt-get install libmemcached-dev + - name: Install Django and its Python test dependencies + run: | + pip3 install -U pip + cd django_repo/tests/ + pip3 install -e .. + pip3 install -r requirements/py3.txt + - name: install the django-snowflake backend + run: pip3 install . + - name: Copy the test settings file + run: cp .github/workflows/snowflake_settings.py django_repo/tests/ + - name: Run the tests + run: > + python3 django_repo/tests/runtests.py --settings snowflake_settings -v 2 + field_defaults + field_subclassing + file_storage + file_uploads + filtered_relation + force_insert_update + foreign_object + forms_tests + from_db_value + generic_inline_admin + generic_relations + generic_relations_regress + generic_views + get_earliest_or_latest + get_object_or_404 + get_or_create + i18n + inline_formsets + inspectdb + introspection + invalid_models_tests + known_related_objects + lookup + m2m_and_m2o + m2m_intermediary + m2m_multiple + m2m_recursive + m2m_regress + m2m_signals + m2m_through + m2m_through_regress + m2o_recursive + managers_regress + many_to_many + many_to_one + many_to_one_null + max_lengths + migrate_signals + migrations + migration_test_data_persistence + modeladmin + model_inheritance + model_inheritance_regress + model_meta + model_options + model_package + model_regress + model_fields + env: + SNOWFLAKE_ACCOUNT: ${{ secrets.SNOWFLAKE_ACCOUNT }} + SNOWFLAKE_PASSWORD: ${{ secrets.SNOWFLAKE_PASSWORD }} + SNOWFLAKE_USER: ${{ secrets.SNOWFLAKE_USER }} + SNOWFLAKE_WAREHOUSE: ${{ secrets.SNOWFLAKE_WAREHOUSE }} diff --git a/.github/workflows/tests4.yml b/.github/workflows/tests4.yml new file mode 100644 index 0000000..9ab068e --- /dev/null +++ b/.github/workflows/tests4.yml @@ -0,0 +1,92 @@ +name: Tests IV + +on: + pull_request: + paths: + - '**.py' + - '!setup.py' + - '.github/workflows/tests4.yml' + +jobs: + django-tests: + runs-on: ubuntu-latest + name: Django Test Suite + steps: + - name: Checkout django-snowflake + uses: actions/checkout@v4 + - name: Checkout Django + uses: actions/checkout@v4 + with: + repository: 'timgraham/django' + ref: 'snowflake-6.1.x' + path: 'django_repo' + - name: Install system packages for Django's Python test dependencies + run: | + sudo apt-get update + sudo apt-get install libmemcached-dev + - name: Install Django and its Python test dependencies + run: | + pip3 install -U pip + cd django_repo/tests/ + pip3 install -e .. + pip3 install -r requirements/py3.txt + - name: install the django-snowflake backend + run: pip3 install . + - name: Copy the test settings file + run: cp .github/workflows/snowflake_settings.py django_repo/tests/ + - name: Run the tests + run: > + python3 django_repo/tests/runtests.py --settings snowflake_settings -v 2 + model_forms + model_formsets + model_formsets_regress + multiple_database + mutually_referential + nested_foreign_keys + null_fk + null_fk_ordering + null_queries + one_to_one + ordering + order_with_respect_to + or_lookups + pagination + prefetch_related + properties + proxy_model_inheritance + proxy_models + queries + queryset_pickle + raw_query + reserved_names + reverse_lookup + save_delete_hooks + schema + select_for_update + select_related + select_related_onetoone + select_related_regress + serializers + servers + signals + sitemaps_tests + sites_framework + sites_tests + string_lookup + swappable_models + syndication_tests + test_client + test_client_regress + timezones + transaction_hooks + transactions + unmanaged_models + update + update_only_fields + validation + view_tests + env: + SNOWFLAKE_ACCOUNT: ${{ secrets.SNOWFLAKE_ACCOUNT }} + SNOWFLAKE_PASSWORD: ${{ secrets.SNOWFLAKE_PASSWORD }} + SNOWFLAKE_USER: ${{ secrets.SNOWFLAKE_USER }} + SNOWFLAKE_WAREHOUSE: ${{ secrets.SNOWFLAKE_WAREHOUSE }} diff --git a/README.md b/README.md index 8168e93..cdc1b9d 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,9 @@ ## Install and usage Use the version of django-snowflake that corresponds to your version of -Django. For example, to get the latest compatible release for Django 6.0.x: +Django. For example, to get the latest compatible release for Django 6.1.x: -`pip install django-snowflake==6.0.*` +`pip install django-snowflake==6.1.*` The minor release number of Django doesn't correspond to the minor release number of django-snowflake. Use the latest minor release of each. diff --git a/django_snowflake/__init__.py b/django_snowflake/__init__.py index 30c7df0..ff26011 100644 --- a/django_snowflake/__init__.py +++ b/django_snowflake/__init__.py @@ -1,4 +1,4 @@ -__version__ = '6.0' +__version__ = '6.1a0' # Check Django compatibility before other imports which may fail if the # wrong version of Django is installed. diff --git a/django_snowflake/features.py b/django_snowflake/features.py index 1ca0e8b..dcf1aa0 100644 --- a/django_snowflake/features.py +++ b/django_snowflake/features.py @@ -46,6 +46,9 @@ class DatabaseFeatures(BaseDatabaseFeatures): # This feature is specific to the Django fork used for testing. supports_limit_in_exists = False supports_json_negative_indexing = False + supports_on_delete_db_cascade = False + supports_on_delete_db_default = False + supports_on_delete_db_null = False supports_over_clause = True supports_partial_indexes = False # https://docs.snowflake.com/en/sql-reference/functions-regexp.html#backreferences @@ -135,6 +138,13 @@ class DatabaseFeatures(BaseDatabaseFeatures): # needs to operate as: # WHERE TO_JSON("MODEL_FIELDS_NULLABLEJSONMODEL"."VALUE":bar) IN (PARSE_JSON('["foo", "bar"]')) 'model_fields.test_jsonfield.TestQuerying.test_key_in', + # More unexpected results when queyring JSONField. + 'model_fields.test_jsonfield.JSONExactNoneDeprecationTests.test_annotation_q_filter', + 'model_fields.test_jsonfield.JSONExactNoneDeprecationTests.test_case_when', + 'model_fields.test_jsonfield.JSONExactNoneDeprecationTests.test_filter', + 'model_fields.test_jsonfield.JSONNullTests.test_filter', + 'model_fields.test_jsonfield.JSONNullTests.test_filter_in', + 'model_fields.test_jsonfield.TestQuerying.test_in', # Invalid argument types for function 'GET': (VARCHAR(14), VARCHAR(3)) 'constraints.tests.CheckConstraintTests.test_validate_jsonfield_exact', 'model_fields.test_jsonfield.TestQuerying.test_has_key_literal_lookup', @@ -146,6 +156,7 @@ class DatabaseFeatures(BaseDatabaseFeatures): # QuerySet.bulk_update() not supported for JSONField: # Expression type does not match column data type, expecting VARIANT # but got VARCHAR(16777216) for column JSON_FIELD + "model_fields.test_jsonfield.JSONNullTests.test_bulk_update", 'queries.test_bulk_update.BulkUpdateTests.test_json_field', # Server-side bug? # CAST(TO_JSON("MODEL_FIELDS_NULLABLEJSONMODEL"."VALUE":d) AS VARIANT) @@ -160,10 +171,12 @@ class DatabaseFeatures(BaseDatabaseFeatures): # Fixed if TO_JSON is removed from the ORDER BY clause (or may be fine # as is as some databases give the ordering that Snowflake does.) 'model_fields.test_jsonfield.TestQuerying.test_ordering_by_transform', + # db_default doesn't work on JSONField (invalid identifier 'DEFAULT'). + 'model_fields.test_jsonfield.JSONNullTests.test_default', # SQL compilation error: is not a valid order by expression. 'ordering.tests.OrderingTests.test_orders_nulls_first_on_filtered_subquery', # Zero pk validation not added yet. - 'backends.tests.MySQLPKZeroTests.test_zero_as_autoval', + 'backends.tests.MySQLAutoPKZeroTests.test_zero_as_autoval', 'bulk_create.tests.BulkCreateTests.test_zero_as_autoval', # Snowflake returns 'The Name::42.00000'. 'db_functions.text.test_concat.ConcatTests.test_concat_non_str', @@ -175,10 +188,18 @@ class DatabaseFeatures(BaseDatabaseFeatures): # expecting VARIANT but got VARCHAR(16777216) for column JSON_FIELD 'expressions.tests.BasicExpressionsTests.test_update_jsonfield_case_when_key_is_null', 'model_fields.test_jsonfield.TestSaveLoad.test_bulk_update_custom_get_prep_value', + 'model_fields.test_jsonfield.JSONNullTests.test_case_expr_with_jsonnull_condition', + 'model_fields.test_jsonfield.JSONNullTests.test_case_expression_with_jsonnull_then', # AssertionError: possibly a server bug that returns the array as a string? 'db_functions.json.test_json_array.JSONArrayTests.test_expressions', # LISTAGG returns empty string rather than NULL 'aggregation.tests.AggregateTestCase.test_stringagg_default_value', + # snowflake-connector-python leaks memory: + # https://github.com/snowflakedb/snowflake-connector-python/issues/2725 + # https://github.com/snowflakedb/snowflake-connector-python/issues/2727 + 'select_related.tests.SelectRelatedTests.test_select_related_memory_leak', + # https://github.com/django/django/pull/20636/changes#r2789583220 + 'proxy_models.tests.ProxyModelTests.test_proxy_included_in_ancestors', } django_test_skips = { @@ -394,7 +415,10 @@ class DatabaseFeatures(BaseDatabaseFeatures): 'composite_pk.test_filter.CompositePKFilterTests.test_filter_comments_by_pk_exact_subquery', 'composite_pk.test_filter.CompositePKFilterTests.test_outer_ref_pk_filter_on_pk_comparison', 'composite_pk.test_filter.CompositePKFilterTests.test_outer_ref_pk_filter_on_pk_exact', - } + }, + "Snowflake doesn't support periods in table names.": { + "ordering.tests.OrderingTests.test_alias_with_period_shadows_table_name", + }, } @cached_property diff --git a/django_snowflake/introspection.py b/django_snowflake/introspection.py index 817845f..bd99bc9 100644 --- a/django_snowflake/introspection.py +++ b/django_snowflake/introspection.py @@ -126,7 +126,11 @@ def get_relations(self, cursor, table_name): table_name = self.connection.ops.quote_name(table_name) cursor.execute(f'SHOW IMPORTED KEYS IN TABLE {table_name}') return { - self.identifier_converter(row[8]): (self.identifier_converter(row[4]), self.identifier_converter(row[3])) + self.identifier_converter(row[8]): ( + self.identifier_converter(row[4]), + self.identifier_converter(row[3]), + self.on_delete_types["NO ACTION"], + ) for row in cursor.fetchall() } diff --git a/setup.cfg b/setup.cfg index 7fe1e6f..86428a8 100644 --- a/setup.cfg +++ b/setup.cfg @@ -11,7 +11,7 @@ long_description_content_type = text/markdown classifiers = Development Status :: 5 - Production/Stable Framework :: Django - Framework :: Django :: 6.0 + Framework :: Django :: 6.1 License :: OSI Approved :: MIT License Operating System :: OS Independent Programming Language :: Python @@ -27,7 +27,7 @@ project_urls = python_requires = >=3.12 packages = find: install_requires = - django >= 6.0, < 6.1 + # django >= 6.1, < 6.2 snowflake-connector-python >= 3.6.0 [flake8]