Comments (10)
database is mysql
from sqlmodel.
del session.refresh(item)
add session.flush()
maybe work
from sqlmodel.
@JeseYe thanks but I want to know why session.refresh not refresh item.
from sqlmodel.
You cannot refresh the item because there is no database instance connected with it.
To do that you need to retrieve the item from the database using an select statement.
You can use refresh in the following:
- retrieve a instance from the database
hero = session.get(Hero, {'name': 'Hans'})
or a select statement - change attributes
hero.age=42
- add to session
session.add(hero)
- write changes
session.commit()
- refresh the instance collected from 1.
session.refresh(hero)
from sqlmodel.
I'm running into this problem myself as well. Pardon my ignorance, but shouldn't SQLModel do this for us? Or is this just something that must be done when using MySQL (assuming this isn't a problem for other DB types)?
from sqlmodel.
I discovered a solution for this:
As it turns out, the object I was passing to the REST endpoint had an ID specified (the ID was 0). When I either don't specify an ID or set it to None prior to adding/committing/refreshing then everything works as desired.
def add_server(item):
with Session(engine) as session:
if item.id == 0:
item.id = None
session.add(item)
session.commit()
session.refresh(item) # now refreshes properly!
return item
from sqlmodel.
Although... again... shouldn't SQLModel (or FastAPI?) determine that since default=None
is specified that it pass id=None
inside the /docs
endpoint? Right now, it passes id=0
for the primary key when I assumed it would've passed id=None
...
id: Optional[int] = Field(default=None, primary_key=True)
from sqlmodel.
Depends on what the default value in the Item schema is, whether 0 or None. However, we shouldn't be having to do this. Using an if condition to check for an id that is passed from a request seems like hacky fix to this problem. If the id is set as the primary key in the models it should be auto incremented by the orm.
from sqlmodel.
I also have this (or, rather, a similar) issue. But in my case I do have both defaults that are not none, and a record with the same primary key in DB.
Code that doesn't work (right now at least)
Models
import uuid
import pydantic
from sqlmodel import Field, Relationship, SQLModel
from .faculty import FacultyModel
class CreateDepartment(SQLModel):
name: str = Field(unique=True, index=True)
description: str | None = Field(default=None, nullable=True)
class DepartmentRepresentation(BaseDepartment):
department_id: pydantic.UUID4
faculties: list[FacultyModel]
class DepartmentModel(BaseDepartment, table=True):
"""
Describes a department in an educational institution.
Highest level of organization in an educational institution.
Departments have a list of associated faculties.
"""
department_id: pydantic.UUID4 = Field(
default_factory=uuid.uuid4,
primary_key=True,
index=True,
)
faculties: list[FacultyModel] = Relationship(back_populates="department")
Endpoint
Code sample:
@admin_router.put(
"/department/{department_id}",
description="Update a department",
)
async def update_department(
db: Annotated[database_session_type, Depends(database_session)],
department_id: str,
department: Annotated[CreateDepartment, Body()],
_: Annotated[DepartmentModel, Depends(department_exists)],
) -> DepartmentRepresentation:
department_obj = DepartmentModel.model_validate(department)
department_obj.department_id = department_id
return update_entity(
db=db,
entity=department_obj,
)
Basically - it takes in the model for a department, and spits out it's representation from the database by performing an update.
I'm using model validation to convert input to the DB model, and set the foreign key to the one specified in path.
department_exists
just verifies that specified department_id
is valid and is present in the DB
Update call
from sqlalchemy.exc import IntegrityError, InvalidRequestError
from sqlmodel import Session, SQLModel
from samurai_backend.errors import SamuraiIntegrityError
...
def update_entity(
db: Session,
entity: SQLModel,
) -> SQLModel:
try:
db.add(entity)
db.commit()
db.refresh(entity)
return entity
except (IntegrityError, InvalidRequestError) as e:
db.rollback()
raise SamuraiIntegrityError from e
Error
I get exception InvalidRequestError
that looks like this:
(psycopg2.errors.UniqueViolation) duplicate key value violates unique constraint "departmentmodel_pkey"\nDETAIL: Key (department_id)=(1523095d-3d9d-46a7-bed5-2e19d3314712) already exists.\n\n[SQL: INSERT INTO departmentmodel (name, description, department_id)...
There's a lengthy INSERT SQL query, which is performed in db.commit()
line. Which is expected, I guess, but not helpful in this case.
Code that does work (right now)
Update the update_entity
and call to it by adding primary_key parameter. In my case it's department_id
, and the method now looks like this:
from sqlalchemy.exc import IntegrityError, InvalidRequestError
from sqlmodel import Session, SQLModel, update
from samurai_backend.errors import SamuraiIntegrityError
...
def update_entity(
db: Session,
entity: SQLModel,
primary_key: str,
) -> SQLModel:
try:
entity_class = entity.__class__
update_query = (
update(entity_class)
.where(getattr(entity_class, primary_key) == getattr(entity, primary_key))
.values(**entity.model_dump(exclude={primary_key}))
)
db.exec(update_query)
db.commit()
return entity
except (IntegrityError, InvalidRequestError) as e:
db.rollback()
raise SamuraiIntegrityError from e
Right now I see this as my only solution, but if you have different ideas, please, let me (or, rather - us) know.
P.S. Just using refresh won't do, since then you will get an error that this object is not in registry yet.
Thanks!
Additional info
I'm using sqlmodel 0.0.16, the latest version at the moment of writing this comment.
from sqlmodel.
had a similar issue, setting auto_increment=True on primary_key id solved it
from sqlmodel.
Related Issues (20)
- `enum.IntFlag` field error when the flag is zero or many field enabled. HOT 1
- The SQL model cannot perform insertion into another table using queried data HOT 2
- not autocompletion
- SQLModel doesn't recognize Relationship between models HOT 1
- Get select with options (selectinload) using response schema HOT 3
- Dose there any better way to write timezone aware datetime field without using the SQLAlchemy ? HOT 3
- Obtaining `TypeError: Cannot pickle 'module' object` on models with many-to-many relationships HOT 2
- Order of columns in the table created does not have 'id' first, despite the order in the SQLModel. Looks like it's prioritising fields with sa_column HOT 6
- Erro ao executar uvicorn.run(...) HOT 1
- Many to many relationship between a table and itself HOT 6
- How to add current date time by default on a table declaration? HOT 13
- Add documentation about how to use the async tools (session, etc) HOT 7
- async relationship bug HOT 14
- 🚀 Roadmap HOT 33
- Internal link failed at create-db-and-table.md
- Field cannot autocompletion when its a SQLModel HOT 7
- Add an overload to the `exec` method with `_Executable` statement for update and delete statements HOT 5
- How to define table prefix name
- docs/contributing.md outdated using poetry HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from sqlmodel.