开发者

Django AutoField not returning new primary_key

We've got a small problem with a Django project we're working on and our postgresql database.

The project we're working on is a site/db conversion from a PHP site to a django site. So we used inspect db to generate the models from the current PHP backend.

It gave us this and we added the primary_key and unique equals True:

class Company(models.Model):
     companyid = models.IntegerField(primary_key=True,unique=True)
     ...
     ...

That didn't seem to be working when we finally got 开发者_如何学JAVAto saving a new Company entry. It would return a not-null constraint error, so we migrated to an AutoField like below:

class Company(models.Model):
     companyid = models.AutoField(primary_key=True)
     ...
     ...

This saves the Company entry fine but the problem is when we do

result = form.save()

We can't do

result.pk or result.companyid

to get the newly given Primary Key in the database (yet we can see that it has been given a proper companyid in the database.

We are at a loss for what is happening. Any ideas or answers would be greatly appreciated, thanks!


I just ran into the same thing, but during a django upgrade of a project with a lot of history. What a pain...

Anyway, the problem seems to result from the way django's postgresql backend gets the primary key for a newly created object: it uses pg_get_serial_sequence to resolve the sequence for a table's primary key. In my case, the id column wasn't created with a serial type, but rather with an integer, which means that my sequence isn't properly connected to the table.column.

The following is based on a table with the create statement, you'll have to adjust your table names, columns and sequence names according to your situation:

CREATE TABLE "mike_test" (
  "id" integer NOT NULL PRIMARY KEY,
  "somefield" varchar(30) NOT NULL UNIQUE
);

The solution if you're using postgresql 8.3 or later is pretty easy:

ALTER SEQUENCE mike_test_id_seq OWNED BY mike_test.id;

If you're using 8.1 though, things are a little muckier. I recreated my column with the following (simplest) case:

ALTER TABLE mike_test ADD COLUMN temp_id serial NOT NULL;
UPDATE mike_test SET temp_id = id;
ALTER TABLE mike_test DROP COLUMN id;
ALTER TABLE mike_test ADD COLUMN id serial NOT NULL PRIMARY KEY;
UPDATE mike_test SET id = temp_id;
ALTER TABLE mike_test DROP COLUMN temp_id;
SELECT setval('mike_test_id_seq', (SELECT MAX(id) FROM mike_test));

If your column is involved in any other constraints, you'll have even more fun with it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜