Używam deklaratywnego rozszerzenia w SQLAlchemy, i zauważyłem dziwny błąd, gdy próbowałem zapisać wystąpienie zmapowanej klasy z niepoprawnymi danymi (konkretnie kolumną zadeklarowaną z wartością zerową = False z wartość Brak).SQLAlchemy podnosi None, powoduje TypeError
Klasa (uproszczony):
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True, autoincrement=True)
userid = Column(String(50), unique=True, nullable=False)
przyczyną błędu (sesja jest sesją SQLAlchemy):
>>> u = User()
>>> session.add(u)
>>> session.commit()
...
TypeError: exceptions must be old-style classes or derived from BaseException, not NoneType
Patrząc na kod, który wywołuje ten wyjątek, znalazłem (w SQLAlchemy. orm.session)
except:
transaction.rollback(_capture_exception=True)
raise
wyjątek wciągnięcia w tym przypadku jest sqlalchemy.exc.Oper ationalError. Jeśli zmienię te linie na:
except Exception as e:
transaction.rollback(_capture_exception=True)
raise e
wtedy problem zniknie, a OperationalError zostanie rzucony zamiast None. Czy jednak oryginalny kod nie powinien działać w żadnej najnowszej wersji Pythona? (Używam 2.7.2) Czy ten błąd jest w jakiś sposób specyficzny dla mojej aplikacji?
Python 2.7.2
SQLAlchemy 0.7.5
UPDATE: błąd wydaje się być specyficzne dla mojego wniosku w jakiś sposób. Zawijam eventlet.db_pool z silnikiem SQLAlchemy, który wydaje się być źródłem problemu. Uruchomienie mojego prostego testu za pomocą SQLite w pamięci lub podstawowego silnika MySQL nie ma tego problemu, ale z db_pool to robi. Sprawa
Test: https://gist.github.com/1980584
Pełne traceback jest:
Traceback (most recent call last):
File "test_case_9525220.py", line 41, in <module>
session.commit()
File "/usr/local/Cellar/python/2.7.2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 645, in commit
self.transaction.commit()
File "/usr/local/Cellar/python/2.7.2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 313, in commit
self._prepare_impl()
File "/usr/local/Cellar/python/2.7.2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 297, in _prepare_impl
self.session.flush()
File "/usr/local/Cellar/python/2.7.2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 1547, in flush
self._flush(objects)
File "/usr/local/Cellar/python/2.7.2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 1635, in _flush
raise
TypeError: exceptions must be old-style classes or derived from BaseException, not NoneType
Jaką wersję sqlalchemy używasz? – Crast
SQLAlchemy 0.7.5 – robbles
czym jest DBAPI (w tym wersja) i jaka jest dokładna natura błędu? OperationalError jest propagowany z DBAPI. Pełny test odtwarzania byłby najlepszy i dołącz go jako bilet do http://www.sqlalchemy.org/trac/newticket – zzzeek