How to do migratiobn in django? - django

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.

Related

Django and south migration: unexpected field came out

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.

How to deal with the required value which does not have a default value in Django model

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

django model field: Why default value not working?

When I create a new row in my PG commander
I let small_price empty because I thought I set a default : 0
small_price = models.IntegerField(default=0)
But when I saved It has an alert :
Reason: null value in column "small_price" violates not-null constraint
Why the default not work??
Do I still need to type 0 when create row??
If you are auto-generating your migrations then you need to make a small edit to the migration before you actually apply it. Go into the generated migration and look for the argument: keep_default=False
in the db.add_column call.
You have to change it to: keep_default=True
This way Django will apply your default value to the actual schema + any existing rows.

django south - unique=True, but "give default value for existing rows" ?

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.

How do I retroactively make AutoFields that don't break django-admin?

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');