цитирование имен столбцов с учетом регистра в фильтре SQLAlchemy

Я пытаюсь запустить запрос фильтра в SQLAlchemy (python), и у меня возникает проблема с чувствительностью к регистру в имени столбца.

Классы моделей автоматически генерируются из схемы следующим образом:

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)

И вот как я запускаю запрос фильтра:

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

Это приводит к ошибке:

sqlalchemy.exc.ProgrammingError: (ProgrammingError) столбец «mycasesensitiveattribute» не существует LINE 3: WHERE myCaseSensitiveAttribute=1

Все остальное работает нормально с учетом регистра. Проблема только в фильтре. Есть ли способ заставить его заключать в кавычки имя столбца без явного определения каждого атрибута в классе модели (в данном случае нецелесообразно) или какой-либо другой рабочий метод фильтрации набора результатов на основе значения переменной?

Спасибо за ваше время!


person drkstr101    schedule 27.09.2013    source источник


Ответы (1)


если вы используете буквальный SQL, quote=True не имеет отношения к тому, что происходит. SQLAlchemy несет ответственность за заключение в кавычки только тогда, когда объекты Table и Column, а не строки, используются для рендеринга SQL. Когда они используются, в подавляющем большинстве случаев, quote=True по-прежнему никогда не требуется, потому что конструкции выражений SQLAlchemy Core автоматически обрабатывают идентификаторы с учетом регистра.

Пример, иллюстрирующий несколько форм использования:

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()
)
person zzzeek    schedule 01.10.2013