I have a constraint like this
CheckConstraint(
check=Q(full_path__endswith=Concat(Value("/"), F("identifier"), Value("/"))) #
| Q(full_path="/"),
name="path_endswith_identifier_if_not_root",
),
Makemigrations runs fine, but when I try to actually migrate the generated migration, I get IndexError: tuple index out of range
...
File "/opt/virtual_env/mch2/lib/python3.7/site-packages/django/db/backends/utils.py", line 99, in execute
return super().execute(sql, params)
File "/opt/virtual_env/mch2/lib/python3.7/site-packages/django/db/backends/utils.py", line 67, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "/opt/virtual_env/mch2/lib/python3.7/site-packages/django/db/backends/utils.py", line 76, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/opt/virtual_env/mch2/lib/python3.7/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
IndexError: tuple index out of range
When I ran sqlmigrations for the generated migration, I get the following error TypeError: not enough arguments for format string
.
Here is the full error message:
...
File "/opt/virtual_env/mch2/lib/python3.7/site-packages/django/db/backends/base/schema.py", line 345, in add_constraint
self.execute(sql)
File "/opt/virtual_env/mch2/lib/python3.7/site-packages/django/db/backends/base/schema.py", line 132, in execute
self.collected_sql.append((sql % tuple(map(self.quote_value, params))) + ending)
TypeError: not enough arguments for format string
The string that django tries to format here is:
ALTER TABLE "documents_directory" ADD CONSTRAINT "path_endswith_identifier_if_not_root" CHECK (("full_path"::text LIKE '%' || REPLACE(REPLACE(REPLACE((CONCAT('/', CONCAT("documents_directory"."identifier", '/'))), E'\\', E'\\\\'), E'%', E'\\%'), E'_', E'\\_') OR "full_path" = '/'))
and the tuple is empty
I have tried the following things to rule out plain stupidity:
- Use
Concat(Value("/"), F("identifier"), Value("/"))
in an annotation, this works like a charm - Replace
Value("/")
with"/"
, as expected this yields problems on its own - Replace the concat in the constraint with a simple value, this also works
So it seems like all pieces of the puzzle work separately!
If it matters, I am using django 2.2.9