#34132 closed Bug (invalid)
Migration with CheckConstraint fails on PostgreSQL in PyPy with psycopg2cffi due to AttributeError
Reported by: | Henryk Plötz | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 4.1 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Description
quote_value
in django/db/backends/postgresql/schema.py
assigns to adapted.encoding
. This is not allowed in psycopg2cffi and raises an AttributeError.
The code path was added in #31815
I'm not sure what the correct fix would be. Simply not assigning encoding
seems wrong. Is what the code tries even possible in cffi?
Steps to reproduce
(I'm using poetry. Also needs apt-get install libpq-dev pypy3 pypy3-dev
or equivalent.)
poetry new demo cd demo poetry env use `which pypy3` poetry add django psycopg2cffi rm -rf demo poetry run django-admin startproject demo cd demo poetry run ./manage.py startapp demo1
in demo/settings.py
add
from psycopg2cffi import compat compat.register()
and add demo1
to INSTALLED_APPS
in demo1/models.py
add
from django.db import models # Create your models here. class Demo1(models.Model): dummy = models.CharField(max_length=23) class Meta: constraints = [ models.CheckConstraint(name="dummy", check=models.Q(dummy__in=["a","b"])) ]
then run
poetry run ./manage.py makemigrations
The file demo1/migrations/0001_initial.py
now contains
# Generated by Django 4.1.3 on 2022-11-02 10:25 from django.db import migrations, models class Migration(migrations.Migration): initial = True dependencies = [ ] operations = [ migrations.CreateModel( name='Demo1', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('dummy', models.CharField(max_length=23)), ], ), migrations.AddConstraint( model_name='demo1', constraint=models.CheckConstraint(check=models.Q(('dummy__in', ['a', 'b'])), name='dummy'), ), ]
Now configure settings for a postgres database (in demo/settings.py
)
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'demo', "USER": "demo", "PASSWORD": "XXXX", "HOST": "XXXX", } }
and run
poetry run ./manage.py migrate
Actual results
Operations to perform: Apply all migrations: admin, auth, contenttypes, demo1, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying admin.0003_logentry_add_action_flag_choices... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying auth.0010_alter_group_name_max_length... OK Applying auth.0011_update_proxy_permissions... OK Applying auth.0012_alter_user_first_name_max_length... OK Applying demo1.0001_initial...Traceback (most recent call last): File "./manage.py", line 22, in <module> main() File "./manage.py", line 18, in main execute_from_command_line(sys.argv) File "/home/henryk/.cache/pypoetry/virtualenvs/demo-gWrR8tCo-py3.8/lib/pypy3.8/site-packages/django/core/management/__init__.py", line 446, in execute_from_command_line utility.execute() File "/home/henryk/.cache/pypoetry/virtualenvs/demo-gWrR8tCo-py3.8/lib/pypy3.8/site-packages/django/core/management/__init__.py", line 440, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File "/home/henryk/.cache/pypoetry/virtualenvs/demo-gWrR8tCo-py3.8/lib/pypy3.8/site-packages/django/core/management/base.py", line 402, in run_from_argv self.execute(*args, **cmd_options) File "/home/henryk/.cache/pypoetry/virtualenvs/demo-gWrR8tCo-py3.8/lib/pypy3.8/site-packages/django/core/management/base.py", line 448, in execute output = self.handle(*args, **options) File "/home/henryk/.cache/pypoetry/virtualenvs/demo-gWrR8tCo-py3.8/lib/pypy3.8/site-packages/django/core/management/base.py", line 96, in wrapped res = handle_func(*args, **kwargs) File "/home/henryk/.cache/pypoetry/virtualenvs/demo-gWrR8tCo-py3.8/lib/pypy3.8/site-packages/django/core/management/commands/migrate.py", line 354, in handle fake_initial=fake_initial, File "/home/henryk/.cache/pypoetry/virtualenvs/demo-gWrR8tCo-py3.8/lib/pypy3.8/site-packages/django/db/migrations/executor.py", line 136, in migrate state, plan, full_plan, fake=fake, fake_initial=fake_initial File "/home/henryk/.cache/pypoetry/virtualenvs/demo-gWrR8tCo-py3.8/lib/pypy3.8/site-packages/django/db/migrations/executor.py", line 168, in _migrate_all_forwards state, migration, fake=fake, fake_initial=fake_initial File "/home/henryk/.cache/pypoetry/virtualenvs/demo-gWrR8tCo-py3.8/lib/pypy3.8/site-packages/django/db/migrations/executor.py", line 252, in apply_migration state = migration.apply(state, schema_editor) File "/home/henryk/.cache/pypoetry/virtualenvs/demo-gWrR8tCo-py3.8/lib/pypy3.8/site-packages/django/db/migrations/migration.py", line 131, in apply self.app_label, schema_editor, old_state, project_state File "/home/henryk/.cache/pypoetry/virtualenvs/demo-gWrR8tCo-py3.8/lib/pypy3.8/site-packages/django/db/migrations/operations/models.py", line 1040, in database_forwards schema_editor.add_constraint(model, self.constraint) File "/home/henryk/.cache/pypoetry/virtualenvs/demo-gWrR8tCo-py3.8/lib/pypy3.8/site-packages/django/db/backends/base/schema.py", line 511, in add_constraint sql = constraint.create_sql(model, self) File "/home/henryk/.cache/pypoetry/virtualenvs/demo-gWrR8tCo-py3.8/lib/pypy3.8/site-packages/django/db/models/constraints.py", line 83, in create_sql check = self._get_check_sql(model, schema_editor) File "/home/henryk/.cache/pypoetry/virtualenvs/demo-gWrR8tCo-py3.8/lib/pypy3.8/site-packages/django/db/models/constraints.py", line 76, in _get_check_sql return sql % tuple(schema_editor.quote_value(p) for p in params) File "/home/henryk/.cache/pypoetry/virtualenvs/demo-gWrR8tCo-py3.8/lib/pypy3.8/site-packages/django/db/models/constraints.py", line 76, in <genexpr> return sql % tuple(schema_editor.quote_value(p) for p in params) File "/home/henryk/.cache/pypoetry/virtualenvs/demo-gWrR8tCo-py3.8/lib/pypy3.8/site-packages/django/db/backends/postgresql/schema.py", line 57, in quote_value adapted.encoding = "utf8" AttributeError: can't set attribute
Expected results
No exception :)
Change History (2)
comment:1 by , 2 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
comment:2 by , 11 months ago
Just for reference, I reported it upstream long time ago, there is a patch there but no merge, the project looks abandoned.
Thanks for the report, however
psycopg2cffi
is not officially supported. Moreover, it's compatible withpsycopg2==2.5
(according to itsREADME
) and Django 4.1 supportspsycopg2
2.8.4
or higher. You should report this on thepsycopg2cffi
bug tracker.