[Question] `sqlalchemy.exc.ProgrammingError: (sqlite3.ProgrammingError) Error binding parameter 1: type 'StringCastedVar' is not supported`
Closed this issue · 2 comments
Hi,
I am trying to create a page of route .../user/[user_id] and then use the user_id value to obtain a row from a table in my database.
Something like:
...
from ..models import User
...
class UserState(rx.State):
...
@classmethod
def get_user_data(cls):
with rx.session() as session:
cls.user = session.exec(
# This is where it errors (User is a model that I have defined elsewhere and a table in the db)
User.select().where(User.user_id == rx.State.user_id)
)
...
data = do_stuff_with_user_data(cls.user)
...
return data
@rx.page("/user/[user_id]")
def user_page():
data = UserState.get_user_data()
# display and modify the data in the frontend
return rx.vstack(...)However, even though I have tried many different ways of getting/passing this value into the query, I always get an error that relates to the value of rx.State.user_id being a Var or a StringCastedVar which is not supported by sqlalchemy (ProgrammingError).
There must be some fundamental missunderstanding from my end on how variables must be passed around and used between the front-end and back-end, but I have been stuck with this for a couple days now and I have found no solution online.
Is there something that I am missing? Is the whole approach wrong and I should interact with the database in a different way?
Thanks in advance!
After some trying out other stuff, instead of using the variable as established in a dynamic route, I have a previous page where the user kind of logs in and a user_id is saved in an AuthenticationState`.
Therefore what I try to do in the User page is to have a form where the user can modify its details (for now, first name and last name)
import reflex as rx
from ..components.authentication import AuthenticationState
from ..models import User
class UserState(rx.State):
# AuthenticationState.user_id is saved in the previous page, where the user "logs in"
# If I print the user_id in the previous page, when saving it i can see its value without any issue and
# even use it to query the database further
user_id: str | None = AuthenticationState.user_id
...
@rx.event
def handle_submit(self, form_data: dict):
if self.user_id is None:
raise ValueError("Not logged in")
with rx.session() as session:
user = session.exec(
# This is where it errors (User is a model that I have defined elsewhere and a table in the db)
user = User.select().where(User.user_id == self.user_id)
).one()
user.first_name = form_data["first_name"]
session.add(user)
session.commit()
def form_when_logged_in() -> rx.Component:
return rx.form(...)
def form_when_not_logged_in() -> rx.Component:
return rx.form(...)
@rx.page("/user")
def user_page():
consultant_id = AuthenticationState.consultant_id
return rx.center(
rx.cond(
consultant_id,
form_when_logged_in(),
form_when_not_logged_in(),
)
)
# display and modify the data in the frontend
return rx.vstack(...)The error keeps on being the same:
sqlalchemy.exc.ProgrammingError: (sqlite3.ProgrammingError) Error binding parameter 1: type 'StringCastedVar' is not supported
I feel like I have tried everything but I keep on getting stuck trying to use the state variables to query the database. I would appreciate a bit of guidance in this.
Thanks!
Apparently I didn't read deeply enough the documentation. Accessing var values from other states.
Using self.get_var_value(OtherState.another_var) solves it, but you have to use async/await.
class UserState(rx.State):
user_id: str | None = None
@rx.event
async def handle_submit(self, form_data: dict):
self.user_id = await self.get_var_value(AuthenticationState.user_id)
...