2011-09-20 365 views
1

我在MySQL中有表和引擎是InnoDB。如果我們使用SQLAlchemy的session.begin_nested,爲什麼不提供更改?

系統配置

mysql --version 
mysql Ver 14.14 Distrib 5.1.58, for redhat-linux-gnu (x86_64) using readline 5.1 
python --version 
Python 2.7 

文件:test.py

from sqlalchemy import create_engine 
engine = create_engine('mysql://test:[email protected]/test1', echo=True) 

from sqlalchemy.ext.declarative import declarative_base 
Base = declarative_base() 

from sqlalchemy import Column, Integer, String 

class User(Base): 
    __tablename__ = 'users' 
    id = Column(Integer, primary_key=True) 
    name = Column(String(length=20)) 
    fullname = Column(String(length=10)) 
    password = Column(String(length=20)) 

    def __init__(self, name, fullname, password): 
     self.name = name 
     self.fullname = fullname 
     self.password = password 

    def __repr__(self): 
     return "<User('%s','%s', '%s')>" % (self.name, self.fullname, self.password) 

Base.metadata.create_all(engine) 

from sqlalchemy.orm import sessionmaker 
Session = sessionmaker(bind=engine) 

session=Session() 

session.begin_nested() 
ed_user = User('ed', 'Ed Jones', 'edspassword') 
session.add(ed_user) 
session.commit() 

之後,我得到控制檯

2011-09-20 12:03:02,067 INFO sqlalchemy.engine.base.Engine SELECT DATABASE() 
2011-09-20 12:03:02,067 INFO sqlalchemy.engine.base.Engine() 
2011-09-20 12:03:02,070 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'character_set%%' 
2011-09-20 12:03:02,071 INFO sqlalchemy.engine.base.Engine() 
2011-09-20 12:03:02,072 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'lower_case_table_names' 
2011-09-20 12:03:02,072 INFO sqlalchemy.engine.base.Engine() 
2011-09-20 12:03:02,073 INFO sqlalchemy.engine.base.Engine SHOW COLLATION 
2011-09-20 12:03:02,074 INFO sqlalchemy.engine.base.Engine() 
2011-09-20 12:03:02,079 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'sql_mode' 
2011-09-20 12:03:02,080 INFO sqlalchemy.engine.base.Engine() 
2011-09-20 12:03:02,081 INFO sqlalchemy.engine.base.Engine DESCRIBE `users` 
2011-09-20 12:03:02,082 INFO sqlalchemy.engine.base.Engine() 
2011-09-20 12:03:02,091 INFO sqlalchemy.engine.base.Engine BEGIN (implicit) 
2011-09-20 12:03:02,092 INFO sqlalchemy.engine.base.Engine SAVEPOINT sa_savepoint_1 
2011-09-20 12:03:02,092 INFO sqlalchemy.engine.base.Engine() 
2011-09-20 12:03:02,095 INFO sqlalchemy.engine.base.Engine INSERT INTO users (name, fullname, password) VALUES (%s, %s, %s) 
2011-09-20 12:03:02,095 INFO sqlalchemy.engine.base.Engine ('ed', 'Ed Jones', 'edspassword') 
2011-09-20 12:03:02,120 INFO sqlalchemy.engine.base.Engine RELEASE SAVEPOINT sa_savepoint_1 
2011-09-20 12:03:02,120 INFO sqlalchemy.engine.base.Engine() 

然後我在數據庫中檢查的此項目,並得到

mysql test1 -p 
mysql> use test1 
Database changed 
mysql> select * from users; 
Empty set (0.00 sec) 

然後我想知道爲什麼沒有進入數據庫。我檢查日誌,發現有SAVEPOINT sa_savepoint_1和RELEASE SAVEPOINT sa_savepoint_1,但沒有提交語句。所以我添加一個額外的提交文件,所以最後幾行是。

session.begin_nested() 
ed_user = User('ed', 'Ed Jones', 'edspassword') 
session.add(ed_user) 
session.commit() 
session.commit() 

然後登錄被chenged到

2011-09-20 12:09:16,847 INFO sqlalchemy.engine.base.Engine BEGIN (implicit) 
2011-09-20 12:09:16,847 INFO sqlalchemy.engine.base.Engine SAVEPOINT sa_savepoint_1 
2011-09-20 12:09:16,848 INFO sqlalchemy.engine.base.Engine() 
2011-09-20 12:09:16,849 INFO sqlalchemy.engine.base.Engine INSERT INTO users (name, fullname, password) VALUES (%s, %s, %s) 
2011-09-20 12:09:16,850 INFO sqlalchemy.engine.base.Engine ('ed', 'Ed Jones', 'edspassword') 
2011-09-20 12:09:16,871 INFO sqlalchemy.engine.base.Engine RELEASE SAVEPOINT sa_savepoint_1 
2011-09-20 12:09:16,871 INFO sqlalchemy.engine.base.Engine() 
2011-09-20 12:09:16,872 INFO sqlalchemy.engine.base.Engine COMMIT 

現在我得到數據庫

mysql> use test1 
Database changed 
mysql> select * from users; 
+----+------+----------+-------------+ 
| id | name | fullname | password | 
+----+------+----------+-------------+ 
| 2 | ed | Ed Jones | edspassword | 
+----+------+----------+-------------+ 
1 row in set (0.00 sec) 

所以這是提交的2倍,如果我們開始保存點任何意義的線?或者是sqlalchemy的begin_nested的這種行爲。

回答

2

編輯由於答案已被接受,爲了使下文中評論的新信息更加清晰,我進行了編輯。

除非您使用autocommit=True,否則交易將自動啓動,因此您無需明確呼叫session.begin()

+0

'InvalidRequestError:事務已經開始。使用subtransactions = True允許subtransactions.' 這是我得到的錯誤,當我改變begin_nested開始:( – Nilesh

+2

你是對的:如果你不使用'autocommit = True',那麼你不需要明確地啓動一個事務,因爲它首次使用時隱式開始(見http://www.sqlalchemy.org/docs/orm/session.html?highlight=begin_nested#autocommit-mode),所以實際上你不應該調用session.begin( )''在所有。 – van

+0

Thx範爲您的幫助。當我使用開始它的工作。但是,當我使用begin_nested我必須提交用戶2聲明。有沒有什麼辦法,我們可以提交,它會添加所有數據在db在begin_nested事務中? – Nilesh

相關問題