question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Unexpected model create behaviour for non-integer primary keys

See original GitHub issue

When primary key is i.e. String, model instance returned from model.object.create has primary key as sequential integer. Once instance is fetched again, primary key is as expected - type and value wise. Postgres behaviour is similar. Returned instance primary key in this case is actually None. Same for UUID type. Once fetched again, everything is as expected.

Could be that problem originates from databases library or incorrect usage of it.

Two copy/paste tests.

import random

import databases
import pytest
import sqlalchemy

import orm
from tests.settings import DATABASE_URL
from tests.test_columns import async_adapter

database = databases.Database(DATABASE_URL, force_rollback=True)
metadata = sqlalchemy.MetaData()


def key():
    return "".join(random.choice("abcdefgh123456") for _ in range(8))


class Model(orm.Model):
    __tablename__ = "model"
    __metadata__ = metadata
    __database__ = database

    id = orm.String(primary_key=True, default=key, max_length=8)
    name = orm.String(max_length=32)


@pytest.fixture(autouse=True, scope="function")
def create_test_database():
    engine = sqlalchemy.create_engine(DATABASE_URL)
    metadata.create_all(engine)
    yield
    metadata.drop_all(engine)


@async_adapter
async def test_pk_1():
    model = await Model.objects.create(name="NAME")
    assert isinstance(model.id, str)


@async_adapter
async def test_pk_2():
    model = await Model.objects.create(name="NAME")
    assert await Model.objects.all() == [model]

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:6
  • Comments:7 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
tomchristiecommented, Apr 20, 2020

@Nipsuli That’s really helpful thanks - we probably ought to update the create method along those lines.

1reaction
aminalaeecommented, Oct 3, 2021

@tomchristie @Nipsuli The proposed solution will work in PostgreSQL but not in MySQL and SQLite. SQLite does not support RETURNING clauses until version 3.35.0 and that is not still supported on current python versions.

For anyone interested, the reason this is happening is that SQLite uses a virtual column ROWID, after an INSERT is done, the driver will call last_insert_rowid() which returns an Integer ROWID. This can be solved by using the RETURNING clause but that’s not available yet.

As far as I know MySQL doesn’t support that either.

Any feedback is appreciated.

Read more comments on GitHub >

github_iconTop Results From Across the Web

2259 (Primary keys should be readonly by default in admin)
When creating a simple model with a non-integer primary key, the Admin interface shows the field as editable, but when making a change,...
Read more >
rails non-integer primary key - Stack Overflow
Ruby on Rails (RoR) likes to emphasise the concept of convention over configuration. Therefore, it seeks to minimialise the amount of configuration.
Read more >
Rules and recommendations for creating primary keys in ...
The primary key value must uniquely identify one and only one record within the table. If the rows are not uniquely identified, ...
Read more >
What's New in SQLAlchemy 1.1?
The new behavior is that the proposed primary key for these Address objects are tracked in a separate dictionary so that we merge...
Read more >
Fix list for IBM WebSphere Application Server V8.5
PH38667, Allow container managed behavior for direct lookups ... PH32738, Applying Plugin fix pack 9.0.5.4 creates an unexpected empty file "c:\program".
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found