1

This is my models.py file which uses AutoField for post_id which is a primary key so it is unique. AutoField does auto incrementing as I have read.

from django.db import models
class Post(models.Model):
    post = models.CharField(max_length=1000,unique=True)
    post_id = models.AutoField(primary_key=True)
    neg = models.IntegerField(default=0)
    pos = models.IntegerField(default=0)
    is_money= models.CharField(max_length=1,default = "y")
    def __str__(self):
        return self.post+"\tScore : "+str(self.neg+self.pos)

I have a startup.py file which adds records to db using the following code. I have used get_or_create function to check if the post exits else create it Post.objects.get_or_create(post = text ,defaults={'neg':0,'pos':0,'is_money':has_money_tags})

def add_to_db(self):
    from reviewer.models import Post
    Post.objects.all().delete()
    import django
    django.setup()
    for num,i in enumerate(self.unlabelled):
        print num
        money_tags=self.getHashTagsfromContent(i[0])
        text = re.sub(r'#[^\s]+',"",i[0])
        y_n=i[1] if i[1].strip()=='y' or i[1].strip()=='n' else  filter(None,map(lambda x : x.strip("]'[ \n\t"),i[1].split(",")))
        if isinstance(y_n,list):
            money_tags=money_tags+y_n
        has_money_tags=y_n if y_n =='y' or y_n=='n' else self.isMoney(money_tags)
        self.logger.info(str(text)+"\t"+str((num+1))+"\t"+str(has_money_tags)+"\n")

        p,created=Post.objects.get_or_create(post = text ,defaults={'neg':0,'pos':0,'is_money':has_money_tags})

def run():
    r=Reviewer_Data()
    r.add_to_db()

This is the Migrations class being created after makemigrations

class Migration(migrations.Migration):

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='Post',
            fields=[
                ('post', models.CharField(unique=True, max_length=1000)),
                ('post_id', models.AutoField(serialize=False, primary_key=True)),
                ('neg', models.IntegerField(default=0)),
                ('pos', models.IntegerField(default=0)),
                ('is_money', models.CharField(default=b'y', max_length=1)),
            ],
        ),
    ]

When I execute python manage.py runserver . It gives me an error for the column post_id django.db.utils.IntegrityError: NOT NULL constraint failed: reviewer_post.post_id

I am trying to add some records in the database during server start and it worked when there were no unique fields but when I updated my models file to make two fields unique post and post_id it started having problems with post_id.

How can I make sure adding a unique field to work?

Any help is appreciated.

Akshay Hazari
  • 3,186
  • 4
  • 48
  • 84
  • The other questions similar to this on SO have not helped solving the problem. And they seem a little different. – Akshay Hazari Jan 04 '16 at 05:59
  • Any particular reason why you are creating your own primary key field as opposed to just using the one auto generated by django? – domino Jan 04 '16 at 06:14
  • @domino I need to use the post_id to fetch records serially. Once I am done with a record on a page the page would redirect to the next record. I thought I could make it a primary key so that I need not use unique and there would be one field less. – Akshay Hazari Jan 04 '16 at 06:18
  • 1
    Django automatically creates a primary key field for you which does exactly what you are trying to do. You don't need to create one yourself. – domino Jan 04 '16 at 06:22
  • @domino Got it `id = models.AutoField(primary_key=True)` Django does that automatically https://docs.djangoproject.com/en/1.9/topics/db/models/#automatic-primary-key-fields – Akshay Hazari Jan 04 '16 at 06:25
  • That still doesn't explain why you are getting the error though... – mastazi Jan 04 '16 at 06:40

1 Answers1

1

I have just started with django and so I had been stuck with this. This is what I tried which worked.

As domino suggested I removed the post_id field which Django automatically handles creating a primary key named id. This is my models.py file now.

from django.db import models
class Post(models.Model):
    post = models.CharField(max_length=1000,unique=True)
    neg = models.IntegerField(default=0)
    pos = models.IntegerField(default=0)
    is_money= models.CharField(max_length=1,default = "y")
    def __str__(self):
        return self.post+"\tScore : "+str(self.neg+self.pos)

I had removed the migrations folder. I hadn't done syncdb earlier.I am still learning and I am far behind with Django.

This is how Adrián Deccico has dropped tables in another answer on SO - How do I drop a table from SQLite3 in DJango?. First I did that and also removed the migrations folder.

./manage.py sqlclear reviewer | ./manage.py dbshell 
./manage.py syncdb

Then python manage.py migrate followed by python manage.py sqlmigrate reviewer 0001 and then python manage.py runserver which worked.

Community
  • 1
  • 1
Akshay Hazari
  • 3,186
  • 4
  • 48
  • 84