⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 session.txt

📁 SQLAlchemy. 经典的Python ORM框架。学习必看。
💻 TXT
📖 第 1 页 / 共 4 页
字号:
As well as `__contains__()`:    {python}    if obj in session:        print "Object is present"The session is also keeping track of all newly created (i.e. pending) objects, all objects which have had changes since they were last loaded or saved (i.e. "dirty"), and everything that's been marked as deleted.      {python}    # pending objects recently added to the Session    session.new        # persistent objects which currently have changes detected    # (this collection is now created on the fly each time the property is called)    session.dirty    # persistent objects that have been marked as deleted via session.delete(obj)    session.deleted### QueryingThe `query()` function takes one or more classes and/or mappers, along with an optional `entity_name` parameter, and returns a new `Query` object which will issue mapper queries within the context of this Session.  For each mapper is passed, the Query uses that mapper.  For each class, the Query will locate the primary mapper for the class using `class_mapper()`.    {python}    # query from a class    session.query(User).filter_by(name='ed').all()    # query with multiple classes, returns tuples    session.query(User).add_entity(Address).join('addresses').filter_by(name='ed').all()        # query from a mapper    query = session.query(usermapper)    x = query.get(1)        # query from a class mapped with entity name 'alt_users'    q = session.query(User, entity_name='alt_users')    y = q.options(eagerload('orders')).all()    `entity_name` is an optional keyword argument sent with a class object, in order to further qualify which primary mapper to be used; this only applies if there was a `Mapper` created with that particular class/entity name combination, else an exception is raised.  All of the methods on Session which take a class or mapper argument also take the `entity_name` argument, so that a given class can be properly matched to the desired primary mapper.All instances retrieved by the returned `Query` object will be stored as persistent instances within the originating `Session`.### Saving New Instances`save()` is called with a single transient instance as an argument, which is then added to the Session and becomes pending.  When the session is next flushed, the instance will be saved to the database.  If the given instance is not transient, meaning it is either attached to an existing Session or it has a database identity, an exception is raised.    {python}    user1 = User(name='user1')    user2 = User(name='user2')    session.save(user1)    session.save(user2)        session.commit()     # write changes to the databaseThere's also other ways to have objects saved to the session automatically; one is by using cascade rules, and the other is by using a contextual session.  Both of these are described later.### Updating/Merging Existing InstancesThe `update()` method is used when you have a detached instance, and you want to put it back into a `Session`.  Recall that "detached" means the object has a database identity.Since `update()` is a little picky that way, most people use `save_or_update()`, which checks for an `_instance_key` attribute, and based on whether it's there or not, calls either `save()` or `update()`:    {python}    # load user1 using session 1    user1 = sess1.query(User).get(5)        # remove it from session 1    sess1.expunge(user1)        # move it into session 2    sess2.save_or_update(user1)`update()` is also an operation that can happen automatically using cascade rules, just like `save()`.  `merge()` on the other hand is a little like `update()`, except it creates a **copy** of the given instance in the session, and returns to you that instance; the instance you send it never goes into the session.  `merge()` is much fancier than `update()`; it will actually look to see if an object with the same primary key is already present in the session, and if not will load it by primary key.  Then, it will merge the attributes of the given object into the one which it just located.This method is useful for bringing in objects which may have been restored from a serialization, such as those stored in an HTTP session, where the object may be present in the session already:    {python}    # deserialize an object    myobj = pickle.loads(mystring)    # "merge" it.  if the session already had this object in the     # identity map, then you get back the one from the current session.    myobj = session.merge(myobj)`merge()` includes an important option called `dont_load`.  When this boolean flag is set to `True`, the merge of a detached object will not force a `get()` of that object from the database.  Normally, `merge()` issues a `get()` for every existing object so that it can load the most recent state of the object, which is then modified according to the state of the given object.  With `dont_load=True`, the `get()` is skipped and `merge()` places an exact copy of the given object in the session.  This allows objects which were retrieved from a caching system to be copied back into a session without any SQL overhead being added.### DeletingThe `delete` method places an instance into the Session's list of objects to be marked as deleted:    {python}    # mark two objects to be deleted    session.delete(obj1)    session.delete(obj2)    # commit (or flush)    session.commit()The big gotcha with `delete()` is that **nothing is removed from collections**.  Such as, if a `User` has a collection of three `Addresses`, deleting an `Address` will not remove it from `user.addresses`:    {python}    >>> address = user.addresses[1]    >>> session.delete(address)    >>> session.flush()    >>> address in user.addresses    TrueThe solution is to use proper cascading:    {python}    mapper(User, users_table, properties={        'addresses':relation(Address, cascade="all, delete")    })    del user.addresses[1]    session.flush()### FlushingThis is the main gateway to what the `Session` does best, which is save everything !  It should be clear by now what a flush looks like:        {python}    session.flush()    It also can be called with a list of objects; in this form, the flush operation will be limited only to the objects specified in the list:    {python}    # saves only user1 and address2.  all other modified    # objects remain present in the session.    session.flush([user1, address2])    This second form of flush should be used carefully as it will not necessarily locate other dependent objects within the session, whose database representation may have foreign constraint relationships with the objects being operated upon.Theres also a way to have `flush()` called automatically before each query; this is called "autoflush" and is described below.Note that when using a `Session` that has been placed into a transaction, the `commit()` method will also `flush()` the `Session` unconditionally before committing the transaction.  Note that flush **does not change** the state of any collections or entity relationships in memory; for example, if you set a foreign key attribute `b_id` on object `A` with the identifier `B.id`, the change will be flushed to the database, but `A` will not have `B` added to its collection.  If you want to manipulate foreign key attributes directly, `refresh()` or `expire()` the objects whose state needs to be refreshed subsequent to flushing.### AutoflushA session can be configured to issue `flush()` calls before each query.  This allows you to immediately have DB access to whatever has been saved to the session.  It's recommended to use autoflush with `transactional=True`, that way an unexpected flush call won't permanently save to the database:    {python}    Session = sessionmaker(autoflush=True, transactional=True)    sess = Session()    u1 = User(name='jack')    sess.save(u1)        # reload user1    u2 = sess.query(User).filter_by(name='jack').one()    assert u2 is u1    # commit session, flushes whatever is remaining    sess.commit()Autoflush is particularly handy when using "dynamic" mapper relations, so that changes to the underlying collection are immediately available via its query interface.### CommittingThe `commit()` method on `Session` is used specifically when the `Session` is in a transactional state.  The two ways that a session may be placed in a transactional state are to create it using the `transactional=True` option, or to call the `begin()` method.  `commit()` serves **two** purposes; it issues a `flush()` unconditionally to persist any remaining pending changes, and it issues a commit to all currently managed database connections.  In the typical case this is just a single connection.  After the commit, connection resources which were allocated by the `Session` are released.  This holds true even for a `Session` which specifies `transactional=True`; when such a session is committed, the next transaction is not "begun" until the next database operation occurs.See the section below on "Managing Transactions" for further detail.### Expunge / ClearExpunge removes an object from the Session, sending persistent instances to the detached state, and pending instances to the transient state:    {python}    session.expunge(obj1)    Use `expunge` when you'd like to remove an object altogether from memory, such as before calling `del` on it, which will prevent any "ghost" operations occurring when the session is flushed.This `clear()` method is equivalent to `expunge()`-ing everything from the Session:        {python}    session.clear()However note that the `clear()` method does not reset any transactional state or connection resources; therefore what you usually want to call instead of `clear()` is `close()`.    ### ClosingThe `close()` method issues a `clear()`, and releases any transactional/connection resources.  When connections are returned to the connection pool, whatever transactional state exists is rolled back.When `close()` is called, the `Session` is in the same state as when it was first created, and is safe to be used again.  `close()` is especially important when using a contextual session, which remains in memory after usage.  By issuing `close()`, the session will be clean for the next request that makes use of it.### Refreshing / ExpiringTo assist with the Session's "sticky" behavior of instances which are present, individual objects can have all of their attributes immediately re-loaded from the database, or marked as "expired" which will cause a re-load to occur upon the next access of any of the object's mapped attributes.  This includes all relationships, so lazy-loaders will be re-initialized, eager relationships will be repopulated.  Any changes marked on the object are discarded:    {python}    # immediately re-load attributes on obj1, obj2    session.refresh(obj1)    session.refresh(obj2)        # expire objects obj1, obj2, attributes will be reloaded    # on the next access:    session.expire(obj1)    session.expire(obj2)`refresh()` and `expire()` also support being passed a list of individual attribute names in which to be refreshed.  These names can reference any attribute, column-based or relation based:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -