I'm using Django 1.6 as a banckend and I'm using South for migration.
I have two tables, Content and Channel, I added a field adress in Channel:
class Channel(models.Model):
name = models.CharField(max_length=256)
adress = models.CharField(max_length=256,null=True)
and I added a ForeignKey in table Content:
class Content(models.Model):
name = models.CharField(max_length=256)
channel = models.ForeignKey(Channel, null=True, blank=True)
When I run the command :
python manage.py schemamigration myapp --auto
I got this:
+ Added field adress on myapp.Channel
? The field 'Content.adress' does not have a default specified, yet is NOT NULL.
? Since you are removing this field, you MUST specify a default
? value to use for existing rows. Would you like to:
? 1. Quit now.
? 2. Specify a one-off value to use for existing columns now
? 3. Disable the backwards migration by raising an exception; you can edit the migration to fix it later
? Please select a choice: Connection to v-atm-t3v closed by remote host.
Why do I have field Content.adress? I marked the ForeignKey as null=True,blank=True because I want it to be blank by default, how can I solve that? Thanks!
The message is basically saying: You were having a field called adress in model Content before, and it's couldn't be null when you defined it(you don't have null=True on that field). When you delete it, south needs to know what value do you want to fill in when you recover the field in case you want to reverse the migration.
If you understand south, it has forward and backward methods, to apply and revert the changes respectively. When you want to undo the migration, your data for field adress on model Content cannot be recovered. But you already made it not nullable, south needs to fill in some value, hence the prompt message.
The solution depends on your need. If you don't bother recovering the values for that field, pick 3 would be OK, because you will never run backwards migration. Or pick 2 but it doesn't do any better than 3, just fill in a default value for all records, which is most likely not what you want.
Related
Django3.2
mysql 5.7
I have a model name hOEEHcQtEckeEGroJCMSGBYeRBDgddrPmvRbFSXFBtktNohn and its length is 48 characters and it has 1 not null field. On mysql5.7 it is working fine.
But when try to upgrade with mysql8+ migrations throws error Identifier name is too long.
This model generates following name in mysql8.5 abcdefg_hOEEHcQtEckeEGroJCMSGBYeRBDgddrPmvRbFSXFBtktNohn _chk_1 it has 65 characters.
mysql8 limit info
I have a question what are the possible solutions to fix this issue on mysql8 ?
You can specify the name at the database side with the db_table Meta option [Django-doc]. For example with:
class BlackboardLearnerAssessmentDataTransmissionAudit(models.Model):
# …
class Meta:
db_table = 'transmission_audit'
You can thus first rename the table and then upgrade the database. If you can start from scratch, I would advise removing the migrations where you start using the BlackboardLearnerAssessmentDataTransmissionAudit model. You thus create all the other models with a single migration such that you never use this long name in the first place, but this assumes that you can start migrating from an empty database.
Initially I migrated one app models after that I added one field there
pol_id = CharField(max_length=25, unique=True)
now if I am running makemigrations its showing me
You are trying to add a non-nullable field 'pol_id' to Health without a default; we can't do that (the database needs something to populate existing rows).
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
In my db there is no any object, I saw many answer to put there null=True, but I can't add null=True in pol_id, is there any hard migration command to fix this issue?
It comes out because you didn't specify default in the field. You don't have to be surprised at all.
If you don't need to specify default for the field in models.py, just select option number 1, and input '' as the default value.
The version of my Django is 1.7.
I have a model named Booking, it has a Boolean field named is_departure, which is used to describe the booking is departure or arrival.
class Booking(models.Model):
...
is_departure = models.BooleanField()
...
When I migrate my app, it will return me a warning that is_departure does not have a default value.
However, I do not want to add a default value for is_departure. This is a required value and it needs to be filled by user. I do not want to use NullBooleanField neither, because is_departure should not be null.
Is there any good way to remove this warning?
The problem is, what will Django put as a value for all the existing rows that now have a is_departure value that according to you, cannot be null, you can't satisfy this constraint.
If you're still developing, then you can reset the DB and you can indeed use BooleanField without default (since there will be no existing rows violating this)
Otherwise, I'd make the migration put a is_departure value (true or false) on the existing rows, consistent with your business logic
I have created an index field
channel_indexid = PositiveIntegerField(db_index=True, unique=True)
If I try to migrate, south is asking me to enter default value for existing rows.
1. Quit now, and add a default...
2. Specify a one-off value..
But, channel_indexid is a unique, how can I give one default value for all rows? is there any workound for this. this is really annoying
Since you are modifying a model, South will ask you for default value for existing rows since your new field, by default is null=False. You can avoid to give it a default value by setting null=True, blank=True.
If you don't want it to be nullable and you still want to add this field as not nullable, then you have to drop the table and create it again with your new field.
South by default give new columns a null value but since by default fields are null=False then South ask you for a value to give to the new field. South does not give empty strings or 0 as default values for string or integer fields, you have to tell South the default value if the field is not nullable, and if it is nullable it will give a default value of null.
I created the models in a Django app using manage.py inspectdb on an
existing postgres database. This seemed to work except that all the
primary keys were described in the models as IntegerFields, which made
them editable in the admin panel, and had to be hand-entered based on
knowledge of the id of the previous record. I just learned about this
after some usage by the client, so I went back to change things like
blog_id = models.IntegerField(primary_key=True)
...to...
blog_id = models.AutoField(primary_key=True)
Now the id fields don't appear in the admin panel (good), but adding new rows
has become impossible (not good).
IntegrityError at /admin/franklins_app/blog/add/
duplicate key value violates unique constraint "blog_pkey"
What's the fix? (Bonus question: is it possible to capture the value that Django is trying to assign as the primary key for the new row?)
The sequence behind the serial field which is your primary key doesn't know about the manually entered records.
Find the maximum value of the primary key:
SELECT MAX(<primary_key>) FROM <your_table>;
Then set the next value of the underlying sequence to a number greater than that:
SELECT SETVAL('<primary_key_seq>', <max_value_in_primary_key_plus_something_for_safety>);
You'll find the name of the sequence (mentioned above as <primary_key_seq>) using:
SELECT pg_get_serial_sequence('<your_table_name>', '<primary_key_column_name');