I want to add a new field to a PostgreSQL database.
It's a not null and unique CharField, like
dyn = models.CharField(max_length=31, null=False, unique=True)
The database already has relevant records, so it's not an option to
- delete the database
- reset the migrations
- wipe the data
- set a default static value.
How to proceed?
Edit
Tried to add a default=uuid.uuid4
dyn = models.CharField(max_length=31, null=False, unique=True, default=uuid.uuid4)
but then I get
Ensure this value has at most 31 characters (it has 36).
Edit 2
If I create a function with .hex (as found here)
def hex_uuid():
"""
The UUID as a 32-character lowercase hexadecimal string
"""
return uuid.uuid4().hex
and use it in the default
dyn = models.CharField(max_length=31, null=False, unique=True, default=hex_uuid)
I'll get
Ensure this value has at most 31 characters (it has 32).
Note: I don't want to simply get a substring of the result, like adjusting the hex_uuid()
to have return str(uuid.uuid4())[:30]
, since that'll increase the collision chances.
CodePudding user response:
I ended up using one of the methods shown by Oleg
def dynamic_default_value():
"""
This function will be called when a default value is needed.
It'll return a 31 length string with a-z, 0-9.
"""
alphabet = string.ascii_lowercase string.digits
return ''.join(random.choices(alphabet, k=31)) # 31 is the length of the string
with
dyn = models.CharField(max_length=31, null=False, unique=True, default=dynamic_default_value)
If the field was max_length of 32 characters then I'd have used the hex_uuid()
present in the question.
If I wanted to make the dynamic field the same as the id
of another existing unique field in the same model, then I'd go through the following steps.
CodePudding user response:
you can reset the migrations or edit it or create new one like:
python manage.py makemigrations name_you_want
after that:
python manage.py migrate same_name
edit: example for funcation:
def generate_default_data():
return datetime.now()
class MyModel(models.Model):
field = models.DateTimeField(default=generate_default_data)