1

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" が存在しません 3 行目: WHERE myCaseSensitiveAttribute=1

他のすべては、大文字と小文字を区別して正常に機能します。問題を引き起こしているのはフィルターだけです。モデルクラスの各属性を明示的に定義せずに列名を強制的に引用する方法はありますか (この場合は実用的ではありません)、または変数値に基づいて結果セットをフィルタリングする他の作業方法はありますか?

御時間ありがとうございます!

4

1 に答える 1

1

リテラル SQL を使用している場合、quote=True は何が起こるかに関係ありません。SQLAlchemy は、文字列ではなく Table および Column オブジェクトが SQL のレンダリングに使用される場合にのみ、引用符を付けます。これらが使用される場合、ほとんどの場合、SQLAlchemy Core の式構造が大文字と小文字を区別する識別子を自動的に処理するため、quote=True は必要ありません。

いくつかの使用形態を示す例:

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()
)
于 2013-10-01T23:55:01.973 に答える