0

私は現在 SQLAlchemy を学んでいますが、この奇妙なことを見つけました。私は人の名前と住所を格納するテーブルを試していましたが、それらを取得するためにこれを使用します:

session.query(User)

そして、最初のアイテムを取得するために、私は試しました:

session.query(User).first()

スローするものDatabaseError

Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    session.query(User).first()
  File "build\bdist.win32\egg\sqlalchemy\orm\query.py", line 2275, in first
    ret = list(self[0:1])
  File "build\bdist.win32\egg\sqlalchemy\orm\query.py", line 2142, in __getitem__
    return list(res)
  File "build\bdist.win32\egg\sqlalchemy\orm\query.py", line 2346, in __iter__
    return self._execute_and_instances(context)
  File "build\bdist.win32\egg\sqlalchemy\orm\query.py", line 2361, in _execute_and_instances
    result = conn.execute(querycontext.statement, self._params)
  File "build\bdist.win32\egg\sqlalchemy\engine\base.py", line 664, in execute
    return meth(self, multiparams, params)
  File "build\bdist.win32\egg\sqlalchemy\sql\elements.py", line 272, in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
  File "build\bdist.win32\egg\sqlalchemy\engine\base.py", line 761, in _execute_clauseelement
    compiled_sql, distilled_params
  File "build\bdist.win32\egg\sqlalchemy\engine\base.py", line 874, in _execute_context
    context)
  File "build\bdist.win32\egg\sqlalchemy\engine\base.py", line 1023, in _handle_dbapi_exception
    exc_info
  File "build\bdist.win32\egg\sqlalchemy\util\compat.py", line 185, in raise_from_cause
    reraise(type(exception), exception, tb=exc_tb)
  File "build\bdist.win32\egg\sqlalchemy\engine\base.py", line 867, in _execute_context
    context)
  File "build\bdist.win32\egg\sqlalchemy\engine\default.py", line 376, in do_execute
    cursor.execute(statement, parameters)
DatabaseError: (DatabaseError) ORA-01036: illegal variable name/number
 'SELECT test_user_uid, test_user_name, test_user_address \nFROM (SELECT test_user."uid" AS test_user_uid, test_user.name AS test_user_name, test_user.address AS test_user_address \nFROM test_user) \nWHERE ROWNUM <= :ROWNUM_1' {'ROWNUM_1': 1}

ただし、すべての行を選択し、クエリ オブジェクトをループすると、必要なものを取得できました。

users = [user for user in session.query(User)]
user1 = users[0]

それだけだ、おかしいと思った。これが私のマッピングクラスです:

class User(Base):
    __tablename__ = 'test_user'

    uid = Column(Integer, primary_key = True)
    name = Column(String(50))
    address = Column(String(100))

    def __repr__(self):
        return "<User (%s, %s)"%(self.name, self.address)

私の最善の推測はSession.query().first()、生成されたクエリで最初の行を探していることです。ただし、作業メソッドはすべての行を取得し、Python で最初の行を選択します。問題は、生成されたクエリ (無効なクエリ) から明らかです。主な質問は、SQLAlchemy が無効なクエリを作成した原因は何ですか?

また、SQLAlchemy では、サブクエリを使用してクエリを作成することで、事態がさら​​に難しくなっていることに気付きました。その動作は意図されていますか?

満足のいく答えが得られることを願っています、ありがとう!

4

1 に答える 1

1

まあ、これに気付くのに時間はかかりませんでした。バージョンの問題であることが判明しました。以前はcx_Oracleバージョン 5.0.2 10g を使用していましたが、バージョン 5.1.2 10g にアップグレードしようとしたところ、問題なく動作しました。

これはおそらく SQLAlchemy の文書化されていないバグです。彼らが言及している場所が見つかりません。

結論: SQLAlchemy の最新バージョン (0.9.0b1) を Oracle 10g で使用する場合は、バージョン 5.1.2 10g より古い cx_Oracle を使用しないでください。

これが役に立てば幸いです。質問を読んでくれてありがとう!

于 2013-11-15T06:05:08.970 に答える