Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>As far as I know, there is no way to get the ORM to issue bulk inserts. I believe the underlying reason is that SQLAlchemy needs to keep track of each object's identity (i.e., new primary keys), and bulk inserts interfere with that. For example, assuming your <code>foo</code> table contains an <code>id</code> column and is mapped to a <code>Foo</code> class:</p> <pre><code>x = Foo(bar=1) print x.id # None session.add(x) session.flush() # BEGIN # INSERT INTO foo (bar) VALUES(1) # COMMIT print x.id # 1 </code></pre> <p>Since SQLAlchemy picked up the value for <code>x.id</code> without issuing another query, we can infer that it got the value directly from the <code>INSERT</code> statement. If you don't need subsequent access to the created objects via the <em>same</em> instances, you can skip the ORM layer for your insert:</p> <pre><code>Foo.__table__.insert().execute([{'bar': 1}, {'bar': 2}, {'bar': 3}]) # INSERT INTO foo (bar) VALUES ((1,), (2,), (3,)) </code></pre> <p>SQLAlchemy can't match these new rows with any existing objects, so you'll have to query them anew to for any subsequent operations.</p> <p>As far as stale data is concerned, it's helpful to remember that the session has no built-in way to know when the database is changed outside of the session. In order to access externally modified data through existing instances, the instances must be marked as <em>expired</em>. This happens by default on <code>session.commit()</code>, but can be done manually by calling <code>session.expire_all()</code> or <code>session.expire(instance)</code>. An example (SQL omitted):</p> <pre><code>x = Foo(bar=1) session.add(x) session.commit() print x.bar # 1 foo.update().execute(bar=42) print x.bar # 1 session.expire(x) print x.bar # 42 </code></pre> <p><code>session.commit()</code> expires <code>x</code>, so the first print statement implicitly opens a new transaction and re-queries <code>x</code>'s attributes. If you comment out the first print statement, you'll notice that the second one now picks up the correct value, because the new query isn't emitted until after the update.</p> <p>This makes sense from the point of view of transactional isolation - you should only pick up external modifications between transactions. If this is causing you trouble, I'd suggest clarifying or re-thinking your application's transaction boundaries instead of immediately reaching for <code>session.expire_all()</code>.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload