user2875230
user2875230

Reputation: 339

TypeError: an integer is required (got type str) when running migrations or running tests

I modified an existing model as below:

It was originally this

class AppAssessment(models.Model):
    contact_uuid = models.CharField(max_length=255)
    step = models.IntegerField(null=True)
    optionId = models.IntegerField(null=True, blank=True)
    user_input = models.TextField(null=True, blank=True)
    title = models.TextField(null=True, blank=True)
    description = models.TextField(null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return (
            f"UUID: {self.contact_uuid} | Step: {self.step} | OptionID: {self.optionId} \n"
            f"| User_Input: {self.user_input} | Title: {self.title} \n"
            f"| Created_at: {self.created_at}"
                        
        )

But I changed contact_uuid to contact_id and changed the model type:

class AppAssessment(models.Model):
    contact_id = models.UUIDField()
    step = models.IntegerField(null=True)
    optionId = models.IntegerField(null=True, blank=True)
    user_input = models.TextField(null=True, blank=True)
    title = models.TextField(null=True, blank=True)
    description = models.TextField(null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return (
            f"UUID: {self.contact_id} | Step: {self.step} | OptionID: {self.optionId} \n"
            f"| User_Input: {self.user_input} | Title: {self.title} \n"
            f"| Created_at: {self.created_at}"
                        
        )

In views.py I was already storing the entries as strings

        store_url_entry = AppAssessment(contact_uuid=contact_uuid, title=title, description=description, step=step, user_input=value, optionId=optionId)
        store_url_entry.save()

I've dropped the database and recreated it but it still fails. I've also restarted the virtual env but it doesn't help.

The error I see is this:

  /home/osboxes/app-hub/venv/lib/python3.6/site-packages/psycopg2/__init__.py:144: UserWarning: The psycopg2 wheel package will be renamed from release 2.8; in order to keep installing from binary please use "pip install psycopg2-binary" instead. For details see: <http://initd.org/psycopg/docs/install.html#binary-install-from-pypi>.
  """)
No changes detected
/home/osboxes/app-hub/venv/lib/python3.6/site-packages/psycopg2/__init__.py:144: UserWarning: The psycopg2 wheel package will be renamed from release 2.8; in order to keep installing from binary please use "pip install psycopg2-binary" instead. For details see: <http://initd.org/psycopg/docs/install.html#binary-install-from-pypi>.
  """)
Operations to perform:
  Apply all migrations: app, admin, auth, authtoken, changes, contenttypes, eventstore, registrations, sessions
Running migrations:
  Applying app.0021_auto_20220413_0328...Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/home/osboxes/app-hub/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
    utility.execute()
  File "/home/osboxes/app-hub/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 375, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/osboxes/app-hub/venv/lib/python3.6/site-packages/django/core/management/base.py", line 323, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/osboxes/app-hub/venv/lib/python3.6/site-packages/django/core/management/base.py", line 364, in execute
    output = self.handle(*args, **options)
  File "/home/osboxes/app-hub/venv/lib/python3.6/site-packages/django/core/management/base.py", line 83, in wrapped
    res = handle_func(*args, **kwargs)
  File "/home/osboxes/app-hub/venv/lib/python3.6/site-packages/django/core/management/commands/migrate.py", line 234, in handle
    fake_initial=fake_initial,
  File "/home/osboxes/app-hub/venv/lib/python3.6/site-packages/django/db/migrations/executor.py", line 117, in migrate
    state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
  File "/home/osboxes/app-hub/venv/lib/python3.6/site-packages/django/db/migrations/executor.py", line 147, in _migrate_all_forwards
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
  File "/home/osboxes/app-hub/venv/lib/python3.6/site-packages/django/db/migrations/executor.py", line 245, in apply_migration
    state = migration.apply(state, schema_editor)
  File "/home/osboxes/app-hub/venv/lib/python3.6/site-packages/django/db/migrations/migration.py", line 124, in apply
    operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
  File "/home/osboxes/app-hub/venv/lib/python3.6/site-packages/django/db/migrations/operations/fields.py", line 112, in database_forwards
    field,
  File "/home/osboxes/app-hub/venv/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 433, in add_field
    definition, params = self.column_sql(model, field, include_default=True)
  File "/home/osboxes/app-hub/venv/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 161, in column_sql
    default_value = self.effective_default(field)
  File "/home/osboxes/app-hub/venv/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 233, in effective_default
    return field.get_db_prep_save(self._effective_default(field), self.connection)
  File "/home/osboxes/app-hub/venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 793, in get_db_prep_save
    return self.get_db_prep_value(value, connection=connection, prepared=False)
  File "/home/osboxes/app-hub/venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 2333, in get_db_prep_value
    value = self.to_python(value)
  File "/home/osboxes/app-hub/venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 2343, in to_python
    return uuid.UUID(**{input_form: value})
  File "/usr/local/lib/python3.6/uuid.py", line 137, in __init__
    hex = hex.replace('urn:', '').replace('uuid:', '')
TypeError: an integer is required (got type str)

The migration file for app.0021_auto_20220413_0328:

# Generated by Django 2.2.20 on 2022-04-13 03:28

from django.db import migrations, models
import django.utils.timezone


class Migration(migrations.Migration):

    dependencies = [
        ('app', '0020_auto_20220411_1610'),
    ]

    operations = [
        migrations.RemoveField(
            model_name='appassessment',
            name='contact_uuid',
        ),
        migrations.AddField(
            name='contact_id',
            field=models.UUIDField(default=django.utils.timezone.now),
            preserve_default=False,
        ),
    ]

Thanks for the help.

Upvotes: 0

Views: 667

Answers (1)

Roham
Roham

Reputation: 2110

I think the problem is coming from your migration file... this line....

field = models.UUIDField(default=django.utils.timezone.now)

because you're trying to populate a UUID field with timezone.now(). So if this migration file is not important for you, just delete it (you need to also delete it's record from your database if this record is there, i.e. django_migrations table) or if this is just a test environment you can simply drop everything from your database and do makemigrations and migrate one more time (after deleting this migration file -> app.0021_auto_20220413_0328).

Important Note: If you want to provide a default value for your UUID field you should use something like (before doing makemigrations and migrate):

from uuid import uuid4

contact_id = models.UUIDField(default=uuid4)

because there are some records in your table and you are trying to add UUID field without default value to them... then Django will ask for default value and I'm afraid there isn't any other way to provide a uuid4() in your default value when Django is asking something like:

Please select a fix:
 1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
 2) Quit, and let me add a default in models.py

Also note that if your records in your old field (contact_uuid) is important for you and you want to add it's value to your new field (contact_id), you should write a custom migration file which is another story.

Upvotes: 1

Related Questions