折腾:
期间,对于已有的代码:
/Users/crifan/dev/dev_root/daryun/SIPEvents/sourcecode/sipevents/sipevents/models.py
class Event(db.Model): __tablename__ = “events” # Columns id = db.Column(db.Integer, primary_key = True, autoincrement = True, nullable=False) #user_openid = db.Column(db.String(64)) #user_openid = db.Column(db.String(64), db.ForeignKey(‘user.openid’)) user_openid = db.Column(db.String(64), db.ForeignKey(‘wechat_users.openid’)) title = db.Column(db.String(128)) start_date = db.Column(db.DateTime) end_date = db.Column(db.DateTime) location = db.Column(db.String(256)) cur_user_num = db.Column(db.Integer) max_user_num = db.Column(db.Integer) is_public = db.Column(db.Boolean) description = db.Column(db.Text) notification_time = db.Column(db.Enum(NotificationTime)) # joiners = db.relationship(‘EventJoiner’, backref=’user’, lazy=’dynamic’) #joiners = db.relationship(‘User’, secondary = event_joiners, backref=’events’) #joiners = db.relationship(‘User’, secondary=event_joiners, backref=’joined_events’,lazy=’dynamic’) joiners = db.relationship(‘User’, secondary=event_joiners, backref=’joined_events’) def __init__(self, # id, user_openid, title = “”, location = “”, start_date = None, end_date = None, cur_user_num = 0, max_user_num = 0, is_public = False, description = “”, notification_time = NotificationTime.NotNotify): # self.id = id self.user_openid = user_openid self.title = title self.location = location self.start_date = start_date self.end_date = end_date self.cur_user_num = cur_user_num self.max_user_num = max_user_num self.is_public = is_public self.description = description self.notification_time = notification_time def __repr__(self): #return u'<Event id=%d user_openid=%s title=%r>’ % (self.id, self.user_openid, self.title) return u'<Event id=%s user_openid=%s title=%r>’ % (self.id, self.user_openid, self.title) |
/Users/crifan/dev/dev_root/daryun/SIPEvents/sourcecode/sipevents/sipevents/views.py
newEvent = Event(user_openid = curUser.openid, title = title, location = location, start_date = startDate, end_date = endDate, cur_user_num = 1, max_user_num = maxUserNum, is_public = is_public, description = description, notification_time = notificationTimeEnum) gLog.debug(‘newEvent=%s’, newEvent) #add self to joiners gLog.debug(“type(curUser)=%s, curUser=%s”, curUser, type(curUser)) newEvent.joiners.append(curUser) gLog.debug(‘added self to joiners, newEvent=%s’, newEvent) db.session.add(newEvent) db.session.commit() gLog.debug(“added new event=%s”, newEvent) |
希望实现:
在
db.session.add(newEvent)
以及:
db.session.commit()
之后,可以得到对应的这个新的event的对象
注:此处的newEvent变量,是提交之前的,其id是为空的
sqlalchemy get object after commit
python – sqlalchemy flush() and get inserted id? – Stack Overflow
db.session.add(newEvent) db.session.refresh(newEvent) db.session.commit() |
搜:
sqlalchemy session refresh flush
Session API — SQLAlchemy 1.1 Documentation
“
flush(objects=None)
Flush all the object changes to the database.
Writes out all pending object creations, deletions and modifications to the database as INSERTs, DELETEs, UPDATEs, etc. Operations are automatically ordered by the Session’s unit of work dependency solver.
Database operations will be issued in the current transactional context and do not affect the state of the transaction, unless an error occurs, in which case the entire transaction is rolled back. You may flush() as often as you like within a transaction to move changes from Python to the database’s transaction buffer.
For autocommit Sessions with no active manual transaction, flush() will create a transaction on the fly that surrounds the entire set of operations into the flush.
Parameters: | objects – Optional; restricts the flush operation to operate only on elements that are in the given collection. This feature is for an extremely narrow set of use cases where particular objects may need to be operated upon before the full flush() occurs. It is not intended for general use. |
refresh(instance, attribute_names=None, lockmode=None)¶
Expire and refresh the attributes on the given instance.
A query will be issued to the database and all attributes will be refreshed with their current database value.
Lazy-loaded relational attributes will remain lazily loaded, so that the instance-wide refresh operation will be followed immediately by the lazy load of that attribute.
Eagerly-loaded relational attributes will eagerly load within the single refresh operation.
Note that a highly isolated transaction will return the same values as were previously read in that same transaction, regardless of changes in database state outside of that transaction – usage ofrefresh() usually only makes sense if non-ORM SQL statement were emitted in the ongoing transaction, or if autocommit mode is turned on.
Parameters: |
|
See also
Refreshing / Expiring – introductory material
”
-》好像如果是refresh,需要autocommit是打开了才可以?
结果refresh出错:
before refresh newEvent=<Event id=None user_openid=oswjmv4X0cCXcfkIwjoDfCkeTVVY title=u’\u6d4b\u8bd5session’> <div–<—————————————————————————— [2016-09-04 21:30:48 +0000] [26600] [ERROR] Error handling request /creat_event Traceback (most recent call last): File “/root/Envs/SIPEvents/lib/python2.7/site-packages/gunicorn/workers/sync.py”, line 135, in handle self.handle_request(listener, req, client, addr) File “/root/Envs/SIPEvents/lib/python2.7/site-packages/gunicorn/workers/sync.py”, line 176, in handle_request respiter = self.wsgi(environ, resp.start_response) File “/root/Envs/SIPEvents/lib/python2.7/site-packages/flask/app.py”, line 2000, in __call__ return self.wsgi_app(environ, start_response) File “/root/Envs/SIPEvents/lib/python2.7/site-packages/flask/app.py”, line 1991, in wsgi_app response = self.make_response(self.handle_exception(e)) File “/root/Envs/SIPEvents/lib/python2.7/site-packages/flask/app.py”, line 1567, in handle_exception reraise(exc_type, exc_value, tb) File “/root/Envs/SIPEvents/lib/python2.7/site-packages/flask/app.py”, line 1988, in wsgi_app response = self.full_dispatch_request() File “/root/Envs/SIPEvents/lib/python2.7/site-packages/flask/app.py”, line 1641, in full_dispatch_request rv = self.handle_user_exception(e) File “/root/Envs/SIPEvents/lib/python2.7/site-packages/flask/app.py”, line 1544, in handle_user_exception reraise(exc_type, exc_value, tb) File “/root/Envs/SIPEvents/lib/python2.7/site-packages/flask/app.py”, line 1639, in full_dispatch_request rv = self.dispatch_request() File “/root/Envs/SIPEvents/lib/python2.7/site-packages/flask/app.py”, line 1625, in dispatch_request return self.view_functions[rule.endpoint](**req.view_args) File “/root/html/SIPEvents/sipevents/views.py”, line 743, in decorated_function return f(*args, **kwargs) File “/root/html/SIPEvents/sipevents/views.py”, line 916, in creat_event db.session.refresh(newEvent) File “/root/Envs/SIPEvents/lib/python2.7/site-packages/sqlalchemy/orm/scoping.py”, line 157, in do return getattr(self.registry(), name)(*args, **kwargs) File “/root/Envs/SIPEvents/lib/python2.7/site-packages/sqlalchemy/orm/session.py”, line 1355, in refresh self._expire_state(state, attribute_names) File “/root/Envs/SIPEvents/lib/python2.7/site-packages/sqlalchemy/orm/session.py”, line 1441, in _expire_state self._validate_persistent(state) File “/root/Envs/SIPEvents/lib/python2.7/site-packages/sqlalchemy/orm/session.py”, line 1869, in _validate_persistent state_str(state)) InvalidRequestError: Instance ‘<Event at 0x7fe3ba0a9490>’ is not persistent within this Session |
换成:
gLog.debug(“before flush newEvent=%s”, newEvent) # db.session.refresh(newEvent) db.session.flush() gLog.debug(“after flush newEvent=%s”, newEvent) |
结果:
是可以的:
before flush newEvent=<Event id=None user_openid=oswjmv4X0cCXcfkIwjoDfCkeTVVY title=u’test’> <div–<—————————————————————————— <div–<—————————————————————————— DEBUG in views [/root/html/SIPEvents/sipevents/views.py:918]: after flush newEvent=<Event id=23 user_openid=oswjmv4X0cCXcfkIwjoDfCkeTVVY title=u’test’> <div–<—————————————————————————— <div–<—————————————————————————— DEBUG in views [/root/html/SIPEvents/sipevents/views.py:920]: added new event=<Event id=23 user_openid=oswjmv4X0cCXcfkIwjoDfCkeTVVY title=u’test’> |
[总结]
SQLAlchemy中,在session去commit提交插入新数据之前,
可以通过:
db.session.flush() |
即可使得,之前query出来的变量对象,已经获得了,相当于插入后的值
比如自增auto increment的id,就从None变成插入后的23了。