-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
DISCLAIMER: This is a very weird bug, I don't know if SQLAlchemy is the problem, but I couldn't reproduce without it, there is a very easy workaround, but I felt like i should report this as it may hide something else.
Describe the bug
Using dict()
on an sqlalchemy.engine.Row
object is producing TypeError: tuple indices must be integers or slices, not str
in a very specific setup (see To Reproduce)
Expected behavior
dict(row)
should return the row as a dict.
To Reproduce
This Dockerfile can show the error:
FROM python:3-alpine
RUN apk add --no-cache g++
RUN pip install --upgrade pip && pip install greenlet
RUN apk del g++
RUN pip install sqlalchemy
RUN echo $'\
from sqlalchemy import create_engine \n\
from sqlalchemy.orm import sessionmaker \n\
\n\
session = sessionmaker(bind=create_engine("sqlite://"))() \n\
result = session.execute("select 1, 2, 3").fetchall() \n\
row = result[0] \n\
\n\
print(dict(row)) \n\
' > script.py
RUN python script.py
Inline code is
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
session = sessionmaker(bind=create_engine("sqlite://"))()
result = session.execute("select 1, 2, 3").fetchall()
row = result[0]
print(dict(row))
Error
Traceback (most recent call last):
File "//script.py", line 8, in <module>
print(dict(row))
File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/row.py", line 104, in __getitem__
return self._data[key]
TypeError: tuple indices must be integers or slices, not str
Versions.
- OS: Alpine 3.13
- Python: 3.9.4
- SQLAlchemy: 1.4.6
- Database: sqlite
- DBAPI: ?
Additional context
The provided Dockerfile is a shrunk down version of what we use:
- A base image with build dependencies installing all libs requiring compilation (greenlet)
- A service image that install extra libs not requiring dependencies (sqlalchemy)
I have noticed that REMOVING or MOVING the RUN apk del g++
AFTER the installation of SQL Alchemy will solve the problem.
I also tried to reproduce in debian, compiling libs instead of wheels. with this Dockerfile and could not reproduce, so maybe it's related to Alpine OR there's something else installed in slim-buster.
FROM python:3-slim-buster
RUN apt-get update && apt-get install -y g++
RUN pip install --upgrade pip && pip install greenlet --no-binary :all:
RUN apt-get remove -y g++
RUN pip install sqlalchemy --no-binary :all:
RUN echo '\
from sqlalchemy import create_engine \n\
from sqlalchemy.orm import sessionmaker \n\
\n\
session = sessionmaker(bind=create_engine("sqlite://"))() \n\
result = session.execute("select 1, 2, 3").fetchall() \n\
row = result[0] \n\
\n\
print(dict(row)) \n\
' > script.py
RUN python script.py
WORKAROUND
Using row._asdict()
will solve the problem.
Have a nice day! and thank you for your amazing work.