2014-01-11 3 views
5

Почему запись не вставлена? Идентификатор возвращается, но когда я проверяю базу данных, нет новой записи.Вставка не работает для сеанса базы данных SQLAlchemy

От models.py

from zope.sqlalchemy import ZopeTransactionExtension 

DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension())) 

И views.py

DBSession.execute(text('INSERT INTO (a,b,c) VALUES (\'a\',\'b\',\'c\') RETURNING id'), params=dict(a=a,b=b,c=c)) 

Я попытался совершить с transaction.commit(), который не получает сообщение об ошибке, но не вставить запись. result.fetchone()[0] получает идентификатор.

И DBSession.commit который получает

assert self.transaction_manager.get().status == ZopeStatus.COMMITTING, "Transaction must be committed using the transaction manager" 

ответ

12

Это потому, что вы не используете ORM для вставки новых строк threfore транзакция не знает, он должен совершить на его собственном, потому что состояние транзакции не отмечено как грязное.

Вставьте следующий код после запроса DBSession.execute в свои views.py.

from zope.sqlalchemy import mark_changed 
session = DBSession() 
session.execute(...your query...) 
mark_changed(session) 

На данный момент сделки должны быть в состоянии должным образом совершить запрос, в качестве альтернативы использовать ORM, чтобы вставить новую строку.

Вот немного больше на эту тему:

https://pypi.python.org/pypi/zope.sqlalchemy/0.7.4#id15

By default, zope.sqlalchemy puts sessions in an 'active' state when they are first used. ORM write operations automatically move the session into a 'changed' state. This avoids unnecessary database commits. Sometimes it is necessary to interact with the database directly through SQL. It is not possible to guess whether such an operation is a read or a write. Therefore we must manually mark the session as changed when manual SQL statements write to the DB.

+0

Хмм с использованием mark_changed (DBSession) 'scoped_session' есть ошибка: объект не имеет атрибута 'TWOPHASE' –

+0

Я рассматриваю только с помощью AutoCommit –

+1

Попробуйте делать что-то вроде этого: 'сессии = DBSession()' ' session.execute (...)' 'mark_changed (session)' Потому что вам нужно использовать ваш фактический сеанс, а не создатель сеанса - я изменяю свой первоначальный ответ, чтобы показать, как он должен выглядеть. – Ergo

3

попробовать

DBSession.flush() 

после выполнения

+0

Это не сработало –