[QUESTION] Django 5.2 Support
Hello !
I've been using django-clickhouse-backend on one of my projects and it's been working great so far, so first of all thank you for your work :)
I was just wondering if there were any plans to support Django 5.2 in the near future ?
After updating it, I'm getting the following error with the ClickHouse version of the SQLInsertCompiler:
(
> self.field_as_sql(field, get_placeholder, value)
for field, get_placeholder, value in zip(fields, get_placeholders, row)
)
for row in value_rows
)
E TypeError: SQLInsertCompiler.field_as_sql() takes 3 positional arguments but 4 were given
It seems the issue comes from this Django 5.2 commit:
https://github.com/django/django/commit/2638b75554d2624dca3062a8da113a47f855f2a2
where they've changed the assemble_as_sql / field_as_sql to send/receive an additional get_placeholder parameter.
If this is the only issue, I can maybe look into suggesting a fix. However, any additional changes required might be difficult, hence my question :)
Thanks !
Temporary workaround while a fix is on the way.
# project/patches/clickhouse.py
"""
Django 5.2 compatibility patch for Clickhouse backend.
This patch updates the Clickhouse backend's SQL compiler classes to be compatible with
Django 5.2's changes to the SQLCompiler classes.
"""
import logging
import types
logger = logging.getLogger(__name__)
def patched_sql_insert_compiler_field_as_sql(self, field, get_placeholder, val):
"""
Take a field and a value intended to be saved on that field, and
return placeholder SQL and accompanying params. Check for raw values,
expressions, and fields with get_placeholder() defined in that order.
When field is None, consider the value raw and use it as the
placeholder, with no corresponding parameters returned.
"""
if field is None:
# A field value of None means the value is raw.
sql, params = val, []
elif hasattr(val, "as_sql"):
# This is an expression, let's compile it.
sql, params = self.compile(val)
elif get_placeholder is not None:
# Some fields (e.g. geo fields) need special munging before
# they can be inserted.
sql, params = get_placeholder(val, self, self.connection), [val]
else:
# Return the common case for the placeholder
sql, params = "%s", [val]
return sql, params
def apply_patch():
"""
Apply the Django 5.2 compatibility patch to Clickhouse backend.
"""
try:
import clickhouse_backend.models.sql.compiler as ch_compiler
except ImportError:
logger.warning("Clickhouse backend not found, skipping patch")
return
# Check if the patch is needed by looking at the Django version
import django
if django.VERSION < (5, 2):
logger.info("Django version is less than 5.2, no patch needed")
return
logger.info("Applying Django 5.2 compatibility patch to Clickhouse backend")
# Patch SQLInsertCompiler
insert_compiler = ch_compiler.SQLInsertCompiler
insert_compiler.field_as_sql = types.MethodType(
patched_sql_insert_compiler_field_as_sql, insert_compiler
)
logger.info("Django 5.2 compatibility patch applied to Clickhouse backend")