Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
### unreleased
### 1.3.1

- fix: #99 update value containing "where" cause exception.
- fix: #97 JSONField error in ClickHouse 24.8.
- fix: tuple function error in ClickHouse 24.8.
- support Django 5.1, update clickhouse-driver to 0.2.9.

### 1.3.0

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Django ClickHouse Database Backend
[![Coverage Status](https://coveralls.io/repos/github/jayvynl/django-clickhouse-backend/badge.svg?branch=main)](https://coveralls.io/github/jayvynl/django-clickhouse-backend?branch=main)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)

Django clickhouse backend is a [django database backend](https://docs.djangoproject.com/en/4.1/ref/databases/) for
Django clickhouse backend is a [django database backend](https://docs.djangoproject.com/en/5.1/ref/databases/) for
[clickhouse](https://clickhouse.com/docs/en/home/) database. This project allows using django ORM to interact with
clickhouse, the goal of the project is to operate clickhouse like operating mysql, postgresql in django.

Expand Down Expand Up @@ -152,7 +152,7 @@ class ClickHouseRouter:
return None
```

You should use [database router](https://docs.djangoproject.com/en/4.1/topics/db/multi-db/#automatic-database-routing) to
You should use [database router](https://docs.djangoproject.com/en/5.1/topics/db/multi-db/#automatic-database-routing) to
automatically route your queries to the right database. In the preceding example, I write a database router which route all
queries from subclasses of `clickhouse_backend.models.ClickhouseModel` or custom migrations with a `clickhouse` hint key to clickhouse.
All other queries are routed to the default database (postgresql).
Expand Down
2 changes: 1 addition & 1 deletion clickhouse_backend/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from clickhouse_backend.utils.version import get_version

VERSION = (1, 3, 0, "final", 0)
VERSION = (1, 3, 1, "final", 0)

__version__ = get_version(VERSION)
5 changes: 2 additions & 3 deletions clickhouse_backend/backend/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,8 @@ def _model_indexes_sql(self, model):
"Refer to https://clickhouse.com/docs/en/engines/table-engines/"
"mergetree-family/mergetree/#table_engine-mergetree-data_skipping-indexes"
)
if (
any(field.db_index for field in model._meta.local_fields)
or getattr(model._meta, "index_together", None)
if any(field.db_index for field in model._meta.local_fields) or getattr(
model._meta, "index_together", None
):
warnings.warn(msg)

Expand Down
12 changes: 6 additions & 6 deletions docs/Fields.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ Clickhouse backend support django builtin fields and clickhouse specific fields.
**Note:** You should always use clickhouse specific fields in new projects.
Support for django built-in fields is only for compatibility with existing third-party apps.

**Note:** [ForeignKey](https://docs.djangoproject.com/en/4.1/ref/models/fields/#foreignkey), [ManyToManyField](https://docs.djangoproject.com/en/4.1/ref/models/fields/#manytomanyfield)
or even [OneToOneField](https://docs.djangoproject.com/en/4.1/ref/models/fields/#onetoonefield) could be used with clickhouse backend.
**Note:** [ForeignKey](https://docs.djangoproject.com/en/5.1/ref/models/fields/#foreignkey), [ManyToManyField](https://docs.djangoproject.com/en/5.1/ref/models/fields/#manytomanyfield)
or even [OneToOneField](https://docs.djangoproject.com/en/5.1/ref/models/fields/#onetoonefield) could be used with clickhouse backend.
But no database level constraints will be added, so there could be some consistency problems.


Expand Down Expand Up @@ -171,9 +171,9 @@ DATABASES = {

Fields importing path: `clickhouse_backend.models.Date[32]Field`

[Dates query](https://docs.djangoproject.com/en/4.1/ref/models/querysets/#dates) is supported by DateField and Date32Field.
[Dates query](https://docs.djangoproject.com/en/5.1/ref/models/querysets/#dates) is supported by DateField and Date32Field.

All [date lookup](https://docs.djangoproject.com/en/4.1/ref/models/querysets/#date) are supported by DateField and Date32Field.
All [date lookup](https://docs.djangoproject.com/en/5.1/ref/models/querysets/#date) are supported by DateField and Date32Field.

Both Nullable and LowCardinality are supported.

Expand Down Expand Up @@ -206,10 +206,10 @@ Fields importing path: `clickhouse_backend.models.DateTime[64]Field`

DateTime64Field have a [`precision`](https://clickhouse.com/docs/en/sql-reference/data-types/datetime64) parameter which default to 6.

[Dates query](https://docs.djangoproject.com/en/4.1/ref/models/querysets/#dates) and [datetimes query](https://docs.djangoproject.com/en/4.1/ref/models/querysets/#datetimes)
[Dates query](https://docs.djangoproject.com/en/5.1/ref/models/querysets/#dates) and [datetimes query](https://docs.djangoproject.com/en/5.1/ref/models/querysets/#datetimes)
are supported by DateTimeField and DateTime64Field.

All [date lookup](https://docs.djangoproject.com/en/4.1/ref/models/querysets/#date) are supported by DateTimeField and DateTime64Field.
All [date lookup](https://docs.djangoproject.com/en/5.1/ref/models/querysets/#date) are supported by DateTimeField and DateTime64Field.

Both Nullable and LowCardinality are supported by DateTime. But LowCardinality is not supported by DateTime64.

Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ classifiers = [
"Framework :: Django :: 4.1",
"Framework :: Django :: 4.2",
"Framework :: Django :: 5.0",
"Framework :: Django :: 5.1",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python",
Expand All @@ -34,7 +35,7 @@ classifiers = [
]
dependencies = [
"django>=3.2",
"clickhouse-driver==0.2.8",
"clickhouse-driver==0.2.9",
]
dynamic = ["version", "readme"]

Expand Down
19 changes: 0 additions & 19 deletions tests/aggregation/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1106,25 +1106,6 @@ def as_sql(self, compiler, connection):
):
Book.objects.annotate(Max("id")).annotate(my_max=MyMax("id__max", "price"))

def test_multi_arg_aggregate(self):
class MyMax(Max):
output_field = DecimalField()

def as_sql(self, compiler, connection):
copy = self.copy()
copy.set_source_expressions(copy.get_source_expressions()[0:1])
return super(MyMax, copy).as_sql(compiler, connection)

with self.assertRaisesMessage(TypeError, "Complex aggregates require an alias"):
Book.objects.aggregate(MyMax("pages", "price"))

with self.assertRaisesMessage(
TypeError, "Complex annotations require an alias"
):
Book.objects.annotate(MyMax("pages", "price"))

Book.objects.aggregate(max_field=MyMax("pages", "price"))

def test_add_implementation(self):
class MySum(Sum):
pass
Expand Down
25 changes: 0 additions & 25 deletions tests/expressions_window/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1157,28 +1157,3 @@ def test_invalid_type_start_value_range(self):
)
)
)

def test_invalid_type_end_row_range(self):
msg = "end argument must be a positive integer, zero, or None, but got 'a'."
with self.assertRaisesMessage(ValueError, msg):
list(
Employee.objects.annotate(
test=Window(
expression=Sum("salary"),
frame=RowRange(end="a"),
)
)
)

def test_invalid_type_start_row_range(self):
msg = "start argument must be a negative integer, zero, or None, but got 'a'."
with self.assertRaisesMessage(ValueError, msg):
list(
Employee.objects.annotate(
test=Window(
expression=Sum("salary"),
order_by=F("hire_date").asc(),
frame=RowRange(start="a"),
)
)
)
Loading