Почему commit не дает изменений, если мы используем session.begin_nested из SQLAlchemy? - PullRequest
1 голос
/ 20 сентября 2011

У меня есть таблица в MySQL, и двигатель InnoDB.

Конфигурация системы

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

file: test.py

from sqlalchemy import create_engine
engine = create_engine('mysql://test:test@localhost/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()

Затем журнал изменяется на

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 раза, если мы запустим точку сохранения?или это поведение begin_nested из sqlalchemy.

1 Ответ

2 голосов
/ 20 сентября 2011

РЕДАКТИРОВАТЬ : , так как ответ был принят, я отредактировал, чтобы сделать его более ясным с точки зрения новой информации, как это определено в комментариях ниже.

Если вы не используете autocommit=True, транзакция запускается автоматически, и поэтому вам не нужно явно вызывать session.begin().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...