I have to connect to a legacy system with a legacy database. The database uses an advantage database server. I’ve forked adsdb-django and modified it to work with python 3 and modern django versions.
I’m now experience the following incompatibility:
the ads db fails with “2154 The data type of a parameter cannot be determined” for queries like e.g.
SELECT ? as "a" in ....
with a parameter 1
According to the database documentation these queries are not supported:
Problem: A parameter by itself in the SELECT list or ORDER BY clause has an ambiguous data type. For example, given the statements “SELECT ? FROM mytable” or “SELECT * FROM myTable ORDER BY ?”, the data type of the parameter in either statement cannot be determined.
Solution: Remove the ambiguous parameter from the statement. The use of the parameter in the SELECT list or ORDER BY clause is generally not meaningful.
The offending queries are generated by e.g. Query.exists()
, which calls q.add_annotation(Value(1), "a")
. As a workaround I’ve implemented a filter in the SQLCompiler like this:
class SQLCompiler(compiler.SQLCompiler):
def filter_query(self):
annotations_to_readd = {}
# find offending annotations
for key, annotation in self.query.annotations.items():
if isinstance(annotation, Value) and isinstance(annotation.value, int):
annotations_to_readd[key] = annotation.value
# remove annotations
for key in annotations_to_readd.keys():
self.query.annotations.pop(key, None)
# Re-add the annotations
for key, value in annotations_to_readd.items():
self.query.add_extra({key: value}, None, None, None, None, None)
self.query.set_extra_mask(list(annotations_to_readd.keys()))
def as_sql(self, with_limits=True, with_col_aliases=True):
self.filter_query()
query, params = super(SQLCompiler, self).as_sql(...)
Is there a better way to achieve my goal?
I would think overriding Query.exists()
would be better, but can I somehow have a custom query class for my database interface?