summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2021-02-07 09:51:48 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2021-02-07 09:51:48 -0500
commit10f05288dca4fdbaa4670dd7ef856e441bdb4adc (patch)
tree41a6651e7db75f25367c2a5ef8df4b07b8e5ecec /examples
parentac1228a87290aca4aa64cec27e640817be932feb (diff)
downloadsqlalchemy-10f05288dca4fdbaa4670dd7ef856e441bdb4adc.tar.gz
Document implicit IO points in ORM
I purposely didn't spend much documentation writing about implicit IO when I first pushed out the asyncio extension because I wanted to get a sense on what kinds of issues people had. Now we know and the answer is predictably "all of them". List out all the known implicit IO points and how to avoid them. Also rename the "adapting lazy loads" section, so that the title is less suggestive that this is a necessary technique. References: #5926 Change-Id: I3933b74bd37a5b06989531adbeade34347db679b
Diffstat (limited to 'examples')
-rw-r--r--examples/asyncio/async_orm.py18
1 files changed, 17 insertions, 1 deletions
diff --git a/examples/asyncio/async_orm.py b/examples/asyncio/async_orm.py
index 52df8bd2f..d3355791c 100644
--- a/examples/asyncio/async_orm.py
+++ b/examples/asyncio/async_orm.py
@@ -6,7 +6,9 @@ for asynchronous ORM use.
import asyncio
from sqlalchemy import Column
+from sqlalchemy import DateTime
from sqlalchemy import ForeignKey
+from sqlalchemy import func
from sqlalchemy import Integer
from sqlalchemy import String
from sqlalchemy.ext.asyncio import AsyncSession
@@ -15,6 +17,7 @@ from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.future import select
from sqlalchemy.orm import relationship
from sqlalchemy.orm import selectinload
+from sqlalchemy.orm import sessionmaker
Base = declarative_base()
@@ -24,8 +27,14 @@ class A(Base):
id = Column(Integer, primary_key=True)
data = Column(String)
+ create_date = Column(DateTime, server_default=func.now())
bs = relationship("B")
+ # required in order to access columns with server defaults
+ # or SQL expression defaults, subsequent to a flush, without
+ # triggering an expired load
+ __mapper_args__ = {"eager_defaults": True}
+
class B(Base):
__tablename__ = "b"
@@ -46,7 +55,13 @@ async def async_main():
await conn.run_sync(Base.metadata.drop_all)
await conn.run_sync(Base.metadata.create_all)
- async with AsyncSession(engine) as session:
+ # expire_on_commit=False will prevent attributes from being expired
+ # after commit.
+ async_session = sessionmaker(
+ engine, expire_on_commit=False, class_=AsyncSession
+ )
+
+ async with async_session() as session:
async with session.begin():
session.add_all(
[
@@ -66,6 +81,7 @@ async def async_main():
# result is a buffered Result object.
for a1 in result.scalars():
print(a1)
+ print(f"created at: {a1.create_date}")
for b1 in a1.bs:
print(b1)