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.

How to make sure sqlmodel doesn't re-use numeric ID's?

See original GitHub issue

First Check

  • I added a very descriptive title to this issue.
  • I used the GitHub search to find a similar issue and didn’t find it.
  • I searched the SQLModel documentation, with the integrated search.
  • I already searched in Google “How to X in SQLModel” and didn’t find any information.
  • I already read and followed all the tutorial in the docs and didn’t find an answer.
  • I already checked if it is not related to SQLModel but to Pydantic.
  • I already checked if it is not related to SQLModel but to SQLAlchemy.

Commit to Help

  • I commit to help with one of those options 👆

Example Code

from sqlmodel import Session, SQLModel, Field, Relationship, create_engine
from typing import Optional, Union, List


class Worker(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str = Field(index=True)


class Transaction(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    worker_id: Optional[int] = Field(index=True, foreign_key="worker.id")


sqlite_file_name = "database.db"
sqlite_url = f"sqlite:///{sqlite_file_name}"
engine = create_engine(sqlite_url)
SQLModel.metadata.create_all(engine)


# Create a worker
with Session(engine) as session:
    worker = Worker(name='Worker 1')
    session.add(worker)
    session.commit()
    session.refresh(worker)

# Create a transaction pointing to this worker
with Session(engine) as session:
    transaction = Transaction(worker_id=worker.id)
    session.add(transaction)
    session.commit()
    session.refresh(transaction)

# Delete the worker
with Session(engine) as session:
    session.delete(worker)
    session.commit()
    
# Print all transactions and workers on database
with Session(engine) as session:
    transactions = session.query(Transaction).all()
    workers = session.query(Worker).all()
    print(transactions)
    print(workers)


# Create a new worker. This worker should not have ID 1
with Session(engine) as session:
    worker = Worker(name='Worker 2')
    session.add(worker)
    session.commit()
    session.refresh(worker)

Description

  • Create a worker
  • Create a transaction pointing to this worker
  • Delete the worker
  • Now the transaction is pointing to a non-existent worker
  • Create a new worker
  • The new worker has the same ID as the deleted worker, i.e., ID = 1. I was expecting a new worker to have ID = 2. I want to have proper auto-incrementation (where values are never reused).

Operating System

Linux

Operating System Details

Arch Linux containing python-sqlalchemy 1.4.39-1

SQLModel Version

0.0.6

Python Version

3.10.5

Additional Context

I am having the same problem as this stackoverflow post

The problem is solved by

[...] setting sqlite_autoincrement=True for a table [...]

SQLAlchemy documentation image

First, I don’t know how to set sqlite_autoincrement with sqlmodel. I tried different things but didn’t work. Second, I tried to create a Relationship containing sa_relationship_kwargs={ "cascade": "all,delete" }, but cascade simply does not work. When I delete the worker neither the transactions pointing to this worker are deleted, nor they become None. They are simply pointing to a non-existent worker.

Then if I create a new worker, the new worker inherits the transactions from the deleted worker, this does not make any sense I would appreciate any idea on how to solve this. If I am able to use sqlite_autoincrement then new workers would never reuse the ID from previous workers, this would be a good solution.

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:5

github_iconTop GitHub Comments

1reaction
meirdevcommented, Aug 5, 2022

Use sqlalchemy <= 1.4.35, there are issues with version X>1.4.35 related to the Relationship field

0reactions
FilipeMarchcommented, Aug 5, 2022

Ok, I downgraded to sqlalchemy==1.4.30 and now it is working, thanks @meirdev

Read more comments on GitHub >

github_iconTop Results From Across the Web

Automatic IDs, None Defaults, and Refreshing Data - SQLModel
Now let's talk a bit about why the id field can't be NULL on the database because it's a primary key, and we...
Read more >
Decimal Numbers - SQLModel
When you use condecimal() you can specify the number of digits and decimal places to support. They will be validated by Pydantic (for...
Read more >
Read Data - SELECT - SQLModel
We are creating a SQLModel Hero class model and creating some records. We will need the Hero model and the engine, but we...
Read more >
Create a Table with SQLModel - Use the Engine
Make sure you are inside of your project directory and with your virtual environment activated as explained in the previous chapter. We will:...
Read more >
Read Connected Data - SQLModel
Now open DB Browser for SQLite and open the database.db file. To SELECT connected data we use the same keywords we have used...
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