Skip to content

Commit a2a840d

Browse files
committed
Add test case and fix some bugs
1 parent 1664e92 commit a2a840d

28 files changed

+6705
-245
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ venv
33
**/__pycache__
44
django_clickhouse_backend.egg-info
55
build
6+
tests/unsupported/

CHANGELOG.md

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,81 @@
1+
0.2.0 (2022-10-26)
2+
---
3+
4+
- Adopt some testcase from django project.
5+
- Fix bugs such as datetime escaping and update field use F expression.
6+
17
0.1.0 (2022-10-16)
28
---
39

4-
- ID worker 接口变动以及配置项调整.
5-
- 支持数据库连接池.
6-
- 重构了 Engine 的实现,更加简洁稳定.
7-
- 数据库相关特性集中在 SQLCompiler 实现.
8-
- 忽略不支持的字段级别 db_index 属性,以及 AlterUniqueTogether 迁移操作,以支持django内置model或第三方model迁移.
10+
- ID worker interface changes and configuration item adjustments.
11+
- Support database connection pool.
12+
- Refactored the implementation of Engine to be more concise and stable.
13+
- Database related features are concentrated in the SQLCompiler implementation.
14+
- Ignore unsupported field-level db_index attribute, and AlterUniqueTogether migration operation in favor of django built-in model or 3rd party model migration.
915

1016
0.0.14 (2022-08-18)
1117
---
1218

13-
- 匹配 Django 4.x
19+
- matches Django 4.x.
1420

1521
0.0.13 (2022-08-18)
1622
---
1723

18-
- 修复了搜索 GenericIPAddressField 字段。
24+
- Fixed searching for GenericIPAddressField field.
1925

2026
0.0.12 (2022-08-09)
2127
---
2228

23-
- 修复了创建表时,多个 order by 字段出错的问题。
29+
- Fixed an issue where multiple order by fields were wrong when creating a table.
2430

2531
0.0.11 (2022-08-01)
2632
---
2733

28-
- 修复了 AlterField migration ,支持 Nullable 到非 Nullable 类型改变,使用提供的默认值更新旧的 `NULL` 值。
34+
- Fixed AlterField migration to support Nullable to non-Nullable type changes, update old `NULL` values with provided defaults.
2935

3036
0.0.10
3137
---
3238

33-
- 支持字段类型变化migration
39+
- Support field type change migration
3440

3541
0.0.9
3642
---
3743

38-
- 修复删除、更新模型对象不能同步执行的问题
44+
- Fixed the problem that deleting and updating model objects could not be executed synchronously
3945

4046
0.0.8
4147
---
4248

43-
- QuerySet 支持 setting 查询,可用传入 Clickhouse 设置项,参考[SETTINGS in SELECT Query](https://clickhouse.com/docs/en/sql-reference/statements/select/#settings-in-select)
44-
- 修复插入数据时不能设置正确的对象id,bulk_create create save 均能展示正确的id
49+
- QuerySet supports setting query, you can pass in Clickhouse setting items, refer to [SETTINGS in SELECT Query](https://clickhouse.com/docs/en/sql-reference/statements/select/#settings-in-select)
50+
- Fixed that the correct object id cannot be set when inserting data, bulk_create and create and save can display the correct id
4551

4652
0.0.7
4753
---
4854

49-
- 数据库连接加入fake_transaction属性,测试时设置这个属性可以使postgresql等支持事物的其他数据库数据不清空
50-
- 加入AutoField类型,映射到Int32
51-
- 完善文档中关于测试/迁移/主键的说明
55+
- The fake_transaction attribute is added to the database connection. Setting this attribute during testing can prevent other database data that supports transactions such as postgresql from being emptied between transaction testcase.
56+
- Added AutoField type, mapped to Int32
57+
- Improve documentation about testing/migration/primary keys
5258

5359
0.0.6
5460
---
5561

56-
- 优化了GenericIPAddressField类型字段在存储ipv4地址时,默认输出类型为Ipv6格式,将其转换为对应的Ipv4类型
62+
- When the GenericIPAddressField type field is optimized to store ipv4 addresses, the default output type is Ipv6 format, and it is converted to the corresponding Ipv4 type
5763

5864
0.0.5
5965
---
6066

61-
- 修复了clickhouse driver转义datetime类型值后,丢失时区的问题
67+
- Fixed the issue that the time zone is lost after the clickhouse driver escapes the datetime type value
6268

6369
0.0.4
6470
---
6571

66-
- 新增PositiveSmallIntegerField, PositiveIntegerField, PositiveBigIntegerField字段类型,分别对应正确的clickhouse uint类型范围。
72+
- Added PositiveSmallIntegerField, PositiveIntegerField, PositiveBigIntegerField field types, corresponding to the correct clickhouse uint type range.
6773

68-
- 修改README,修正关于单元测试的说明。
74+
- Modified the README and corrected the description about unit testing.
6975

7076
0.0.3
7177
---
7278

73-
- 解决了多app时,clickhouse.models 中 options.DEFAULT_NAMES monkey patch未生效的问题。
79+
- Solved the problem that the options.DEFAULT_NAMES monkey patch in clickhouse.models did not take effect when there were multiple apps.
7480

75-
- 完善README,增加了自增主键的说明,调整了格式。
81+
- Improve the README, add the description of the auto-increment primary key, and adjust the format.

clickhouse_backend/backend/base.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818

1919
class DatabaseWrapper(BaseDatabaseWrapper):
20-
vendor = 'clickhouse_backend'
20+
vendor = 'clickhouse'
2121
display_name = 'ClickHouse'
2222
# This dictionary maps Field objects to their associated ClickHouse column
2323
# types, as strings. Column-type strings can contain format strings; they'll
@@ -45,6 +45,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
4545
'SmallIntegerField': 'Int16',
4646
'TextField': 'String',
4747
'UUIDField': 'UUID',
48+
'BooleanField': 'Int8',
4849
}
4950
operators = {
5051
'exact': '= %s',
@@ -108,7 +109,7 @@ def fake_transaction(self, value):
108109

109110
def get_connection_params(self):
110111
settings_dict = self.settings_dict
111-
if len(settings_dict['NAME']) > self.ops.max_name_length():
112+
if len(settings_dict['NAME'] or '') > self.ops.max_name_length():
112113
raise ImproperlyConfigured(
113114
"The database name '%s' (%d characters) is longer than "
114115
"Clickhouse's limit of %d characters. Supply a shorter NAME "

clickhouse_backend/backend/features.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55

66
class DatabaseFeatures(BaseDatabaseFeatures):
7-
# Use this class attribute control whether or not using fake transaction.
7+
# Use this class attribute control whether using fake transaction.
88
# Fake transaction is used in test, prevent other database such as postgresql
99
# from flush at the end of each testcase. Only use this feature when you are
10-
# aware of the affect in TransactionTestCase.
10+
# aware of the effect in TransactionTestCase.
1111
fake_transaction = False
1212
# Clickhouse do support Geo Data Types, but they are based on GeoJSON instead GIS.
1313
# https://clickhouse.com/docs/en/sql-reference/data-types/geo/
@@ -116,10 +116,13 @@ def uses_savepoints(self):
116116
# Does the backend support non-deterministic collations?
117117
supports_non_deterministic_collations = False
118118

119+
# SQL template override for tests.aggregation.tests.NowUTC
120+
test_now_utc_template = 'now64()'
121+
119122
@cached_property
120123
def supports_explaining_query_execution(self):
121124
"""Does this backend support explaining query execution?"""
122-
return False
125+
return True
123126

124127
@cached_property
125128
def supports_transactions(self):

clickhouse_backend/backend/introspection.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
1+
import re
2+
13
from django.db.backends.base.introspection import (
24
BaseDatabaseIntrospection, FieldInfo, TableInfo,
35
)
6+
from django.utils.functional import cached_property
7+
8+
constraint_pattern = re.compile(
9+
r'CONSTRAINT (`)?((?(1)(?:[^\\`]|\\.)+|\S+))(?(1)`|) (CHECK .+?),?\n'
10+
)
11+
index_pattern = re.compile(
12+
r'INDEX (`)?((?(1)(?:[^\\`]|\\.)+|\S+))(?(1)`|) (.+? TYPE ([a-zA-Z_][0-9a-zA-Z_]*)\(.+?\) GRANULARITY \d+)'
13+
)
414

515

616
class DatabaseIntrospection(BaseDatabaseIntrospection):
@@ -70,3 +80,46 @@ def get_table_description(self, cursor, table_name):
7080
)
7181
for line in cursor.fetchall()
7282
]
83+
84+
def get_constraints(self, cursor, table_name):
85+
"""
86+
Retrieve any constraints and indexes.
87+
"""
88+
constraints = {}
89+
# No way to get structured data, parse from SHOW CREATE TABLE.
90+
# https://clickhouse.com/docs/en/sql-reference/statements/show#show-create-table
91+
cursor.execute('SHOW CREATE TABLE "%s"' % table_name)
92+
table_sql, = cursor.fetchone()
93+
for backtick, name, definition in constraint_pattern.findall(table_sql):
94+
constraints[name] = {
95+
"columns": [],
96+
"primary_key": False,
97+
"unique": False,
98+
"foreign_key": None,
99+
"check": True,
100+
"index": False,
101+
"definition": definition,
102+
"options": None,
103+
}
104+
105+
for backtick, name, definition, type_ in index_pattern.findall(table_sql):
106+
constraints[name] = {
107+
"columns": [],
108+
"orders": [],
109+
"primary_key": False,
110+
"unique": False,
111+
"foreign_key": None,
112+
"check": False,
113+
"index": True,
114+
"type": type_,
115+
"definition": definition,
116+
"options": None,
117+
}
118+
return constraints
119+
120+
@cached_property
121+
def settings(self):
122+
with self.connection.cursor() as cursor:
123+
cursor.execute("SELECT name from system.settings")
124+
rows = cursor.fetchall()
125+
return {row[0] for row in rows}

0 commit comments

Comments
 (0)