Pergunta

I am trying to run a filter query in SQLAlchemy (python) and I am running into an issue with case sensitivity in the column name.

The model classes are auto-generated from the schema like so:

Base = declarative_base()
engine = create_engine('postgresql://user:pass@localhost:5432/database')
metadata = MetaData(bind=engine)

class MyTable(Base):
    __table__ = Table('my_table', metadata, autoload=True, quote=True)

And here is how I am running the filter query:

val = 1
result = session.query(MyTable).filter("myCaseSensitiveAttribute=:myCaseSensitiveAttribute").params(myCaseSensitiveAttribute=val).all()

This results in the error:

sqlalchemy.exc.ProgrammingError: (ProgrammingError) column "mycasesensitiveattribute" does not exist LINE 3: WHERE myCaseSensitiveAttribute=1

Everything else works fine with case sensitivity. It is only the filter that is causing the issue. Is there a way to force it to quote the column name without explicitly defining each attribute in the model class (not practical in this case), or some other working method of filtering the result set based on a variable value?

Thanks for your time!

Foi útil?

Solução

if you're using literal SQL, quote=True has no bearing upon what happens. SQLAlchemy only has responsibility for quoting when Table and Column objects, not strings, are used to render SQL. When these are used, in the vast majority of cases, quote=True is still never needed because SQLAlchemy Core expression constructs handle case-sensitive identifiers automatically.

Example, illustrating several forms of usage:

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

engine = create_engine('postgresql://scott:tiger@localhost:5432/test')
conn = engine.connect()
trans = conn.begin()

conn.execute('create table "SomeCaseTable" ("SomeAttribute" varchar(20) primary key)')
conn.execute('''insert into "SomeCaseTable" ("SomeAttribute") values ('some data')''')
metadata = MetaData(bind=conn)

class MyTable(Base):
    __table__ = Table('SomeCaseTable', metadata, autoload=True)

session = Session(conn)
val = 'some data'

# example 1: use SQL expressions
print(
    session.query(MyTable).
        filter(MyTable.SomeAttribute == val).
        all()
)

# example 2: totally literal SQL - you need to quote manually
print(
    session.query(MyTable).
        filter('"SomeAttribute"=:some_attribute').
        params(some_attribute=val).all()
)

# example 3: bound param with SQL expressions
print(
    session.query(MyTable).
        filter(MyTable.SomeAttribute == bindparam('somevalue')).
        params(somevalue=val).all()
)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top