Search code examples
pythondjangounit-testingdjango-unittest

Django Unit testing, unknown column error


I'm a Django beginner and am getting acquainted to using it, and I'm also a big believer in unit testing.

Given a sample database table contracts with the fields

parent_id  int
contract_num  varchar
start_date  date
end_date  date
org_name varchar

I defined a model class by using django_admin.py inspectdb > models.py

class Contracts(models.Model):
   parent_id = models.IntegerField()
   contract_num = models.CharField(max_length=10L, db_column='contract_num') 
   start_date = models.DateField()
   end_date = models.DateField(null=True, blank=True)
   org_name = models.CharField(max_length=100L, db_column='org_name')     
   class Meta:
     db_table = 'contracts'

Within the test class, I defined

def setUp(self):
    self.contracts = Contracts(parent_id = 300, contract_num = "1234", start_date = timezone.now(), end_date = None, org_name = "TestContractName")


def test_contracts_access(self):
    self.contracts.save()
    getContracts = Contracts.objects.get(parent_id = 300)

    self.assertEqual(getContracts.org_name, "TestContractName")
    self.assertEqual(getContracts.contract_num, "1234")
    self.assertEquals(getContracts.contract_num, "12")


    getContracts.org_name = "TestContractNameUpdate"
    getContracts.save()

    updateContract = Contracts.objects.get(contract_num = "1234")
    self.assertEqual(updateContract.org_name, "TestContractNameUpdate")

When I run this test, I get a database error 1054: "Unknown column contracts.id in field list". What exactly does that mean? The first error in the stack trace is the get call right after the first save.

Thing is, I have an exact same test set up for another model object and that one passes.


Solution

  • Make sure to check the primary key that is set in the database. If you have a primary key that is on a field not labeled "id" (I'm looking at you parent_id...), then you need to set this in your model. You can do this with :

    field_name = models.AutoField(primary_key=True)
    

    If you do not do this, then Django will look for the field "id", assuming that you have one and that it is your primary key. I think you are getting this error because it is looking for contracts.id which does not exist!

    Check out the Django docs on primary-key-fields and legacy databses.