]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
format collections.rst
authorDoctor <thirvondukr@gmail.com>
Mon, 25 Apr 2022 01:35:20 +0000 (04:35 +0300)
committerDoctor <thirvondukr@gmail.com>
Mon, 25 Apr 2022 01:35:20 +0000 (04:35 +0300)
doc/build/orm/collections.rst

index 716fea74e34a4b512443526816befb3da4d6a3c3..891e5ff524507df5acae88ed6dc70daa0b5e2769 100644 (file)
@@ -48,14 +48,15 @@ when accessed. Filtering criterion may be applied as well as limits and
 offsets, either explicitly or via array slices::
 
     class User(Base):
-        __tablename__ = 'user'
+        __tablename__ = "user"
 
         posts = relationship(Post, lazy="dynamic")
 
+
     jack = session.get(User, id)
 
     # filter Jack's blog posts
-    posts = jack.posts.filter(Post.headline=='this is a post')
+    posts = jack.posts.filter(Post.headline == "this is a post")
 
     # apply array slices
     posts = jack.posts[5:20]
@@ -63,10 +64,10 @@ offsets, either explicitly or via array slices::
 The dynamic relationship supports limited write operations, via the
 :meth:`_orm.AppenderQuery.append` and :meth:`_orm.AppenderQuery.remove` methods::
 
-    oldpost = jack.posts.filter(Post.headline=='old post').one()
+    oldpost = jack.posts.filter(Post.headline == "old post").one()
     jack.posts.remove(oldpost)
 
-    jack.posts.append(Post('new post'))
+    jack.posts.append(Post("new post"))
 
 Since the read side of the dynamic relationship always queries the
 database, changes to the underlying collection will not be visible
@@ -81,9 +82,7 @@ function in conjunction with ``lazy='dynamic'``::
     class Post(Base):
         __table__ = posts_table
 
-        user = relationship(User,
-                    backref=backref('posts', lazy='dynamic')
-                )
+        user = relationship(User, backref=backref("posts", lazy="dynamic"))
 
 Note that eager/lazy loading options cannot be used in conjunction dynamic relationships at this time.
 
@@ -111,9 +110,9 @@ A "noload" relationship never loads from the database, even when
 accessed.   It is configured using ``lazy='noload'``::
 
     class MyClass(Base):
-        __tablename__ = 'some_table'
+        __tablename__ = "some_table"
 
-        children = relationship(MyOtherClass, lazy='noload')
+        children = relationship(MyOtherClass, lazy="noload")
 
 Above, the ``children`` collection is fully writeable, and changes to it will
 be persisted to the database as well as locally available for reading at the
@@ -127,9 +126,9 @@ Alternatively, a "raise"-loaded relationship will raise an
 emit a lazy load::
 
     class MyClass(Base):
-        __tablename__ = 'some_table'
+        __tablename__ = "some_table"
 
-        children = relationship(MyOtherClass, lazy='raise')
+        children = relationship(MyOtherClass, lazy="raise")
 
 Above, attribute access on the ``children`` collection will raise an exception
 if it was not previously eagerloaded.  This includes read access but for
@@ -166,11 +165,12 @@ values accessible through an attribute on the parent instance. By default,
 this collection is a ``list``::
 
     class Parent(Base):
-        __tablename__ = 'parent'
+        __tablename__ = "parent"
         parent_id = Column(Integer, primary_key=True)
 
         children = relationship(Child)
 
+
     parent = Parent()
     parent.children.append(Child())
     print(parent.children[0])
@@ -181,12 +181,13 @@ default list, by specifying the :paramref:`_orm.relationship.collection_class` o
 :func:`~sqlalchemy.orm.relationship`::
 
     class Parent(Base):
-        __tablename__ = 'parent'
+        __tablename__ = "parent"
         parent_id = Column(Integer, primary_key=True)
 
         # use a set
         children = relationship(Child, collection_class=set)
 
+
     parent = Parent()
     child = Child()
     parent.children.add(child)
@@ -203,24 +204,28 @@ to achieve a simple dictionary collection.  It produces a dictionary class that
 of the mapped class as a key.   Below we map an ``Item`` class containing
 a dictionary of ``Note`` items keyed to the ``Note.keyword`` attribute::
 
-    from sqlalchemy import Column, Integer, String, ForeignKey
+    from sqlalchemy import Column, ForeignKey, Integer, String
+    from sqlalchemy.ext.declarative import declarative_base
     from sqlalchemy.orm import relationship
     from sqlalchemy.orm.collections import attribute_mapped_collection
-    from sqlalchemy.ext.declarative import declarative_base
 
     Base = declarative_base()
 
+
     class Item(Base):
-        __tablename__ = 'item'
+        __tablename__ = "item"
         id = Column(Integer, primary_key=True)
-        notes = relationship("Note",
-                    collection_class=attribute_mapped_collection('keyword'),
-                    cascade="all, delete-orphan")
+        notes = relationship(
+            "Note",
+            collection_class=attribute_mapped_collection("keyword"),
+            cascade="all, delete-orphan",
+        )
+
 
     class Note(Base):
-        __tablename__ = 'note'
+        __tablename__ = "note"
         id = Column(Integer, primary_key=True)
-        item_id = Column(Integer, ForeignKey('item.id'), nullable=False)
+        item_id = Column(Integer, ForeignKey("item.id"), nullable=False)
         keyword = Column(String)
         text = Column(String)
 
@@ -231,7 +236,7 @@ a dictionary of ``Note`` items keyed to the ``Note.keyword`` attribute::
 ``Item.notes`` is then a dictionary::
 
     >>> item = Item()
-    >>> item.notes['a'] = Note('a', 'atext')
+    >>> item.notes["a"] = Note("a", "atext")
     >>> item.notes.items()
     {'a': <__main__.Note object at 0x2eaaf0>}
 
@@ -242,9 +247,9 @@ key we supply must match that of the actual ``Note`` object::
 
     item = Item()
     item.notes = {
-                'a': Note('a', 'atext'),
-                'b': Note('b', 'btext')
-            }
+        "a": Note("a", "atext"),
+        "b": Note("b", "btext"),
+    }
 
 The attribute which :func:`.attribute_mapped_collection` uses as a key
 does not need to be mapped at all!  Using a regular Python ``@property`` allows virtually
@@ -253,17 +258,20 @@ below when we establish it as a tuple of ``Note.keyword`` and the first ten lett
 of the ``Note.text`` field::
 
     class Item(Base):
-        __tablename__ = 'item'
+        __tablename__ = "item"
         id = Column(Integer, primary_key=True)
-        notes = relationship("Note",
-                    collection_class=attribute_mapped_collection('note_key'),
-                    backref="item",
-                    cascade="all, delete-orphan")
+        notes = relationship(
+            "Note",
+            collection_class=attribute_mapped_collection("note_key"),
+            backref="item",
+            cascade="all, delete-orphan",
+        )
+
 
     class Note(Base):
-        __tablename__ = 'note'
+        __tablename__ = "note"
         id = Column(Integer, primary_key=True)
-        item_id = Column(Integer, ForeignKey('item.id'), nullable=False)
+        item_id = Column(Integer, ForeignKey("item.id"), nullable=False)
         keyword = Column(String)
         text = Column(String)
 
@@ -290,12 +298,15 @@ object directly::
 
     from sqlalchemy.orm.collections import column_mapped_collection
 
+
     class Item(Base):
-        __tablename__ = 'item'
+        __tablename__ = "item"
         id = Column(Integer, primary_key=True)
-        notes = relationship("Note",
-                    collection_class=column_mapped_collection(Note.__table__.c.keyword),
-                    cascade="all, delete-orphan")
+        notes = relationship(
+            "Note",
+            collection_class=column_mapped_collection(Note.__table__.c.keyword),
+            cascade="all, delete-orphan",
+        )
 
 as well as :func:`.mapped_collection` which is passed any callable function.
 Note that it's usually easier to use :func:`.attribute_mapped_collection` along
@@ -303,12 +314,15 @@ with a ``@property`` as mentioned earlier::
 
     from sqlalchemy.orm.collections import mapped_collection
 
+
     class Item(Base):
-        __tablename__ = 'item'
+        __tablename__ = "item"
         id = Column(Integer, primary_key=True)
-        notes = relationship("Note",
-                    collection_class=mapped_collection(lambda note: note.text[0:10]),
-                    cascade="all, delete-orphan")
+        notes = relationship(
+            "Note",
+            collection_class=mapped_collection(lambda note: note.text[0:10]),
+            cascade="all, delete-orphan",
+        )
 
 Dictionary mappings are often combined with the "Association Proxy" extension to produce
 streamlined dictionary views.  See :ref:`proxying_dictionaries` and :ref:`composite_association_proxy`
@@ -357,7 +371,7 @@ if the value of ``B.data`` is not set yet, the key will be ``None``::
 
 Setting ``b1.data`` after the fact does not update the collection::
 
-    >>> b1.data = 'the key'
+    >>> b1.data = "the key"
     >>> a1.bs
     {None: <test3.B object at 0x7f7b1023ef70>}
 
@@ -365,14 +379,14 @@ Setting ``b1.data`` after the fact does not update the collection::
 This can also be seen if one attempts to set up ``B()`` in the constructor.
 The order of arguments changes the result::
 
-    >>> B(a=a1, data='the key')
+    >>> B(a=a1, data="the key")
     <test3.B object at 0x7f7b10114280>
     >>> a1.bs
     {None: <test3.B object at 0x7f7b10114280>}
 
 vs::
 
-    >>> B(data='the key', a=a1)
+    >>> B(data="the key", a=a1)
     <test3.B object at 0x7f7b10114340>
     >>> a1.bs
     {'the key': <test3.B object at 0x7f7b10114340>}
@@ -384,9 +398,9 @@ An event handler such as the following may also be used to track changes in the
 collection as well::
 
     from sqlalchemy import event
-
     from sqlalchemy.orm import attributes
 
+
     @event.listens_for(B.data, "set")
     def set_item(obj, value, previous, initiator):
         if obj.a is not None:
@@ -394,8 +408,6 @@ collection as well::
             obj.a.bs[value] = obj
             obj.a.bs.pop(previous)
 
-
-
 .. autofunction:: attribute_mapped_collection
 
 .. autofunction:: column_mapped_collection
@@ -585,8 +597,8 @@ from within an already instrumented call can cause events to be fired off
 repeatedly, or inappropriately, leading to internal state corruption in
 rare cases::
 
-    from sqlalchemy.orm.collections import MappedCollection,\
-                                        collection
+    from sqlalchemy.orm.collections import MappedCollection, collection
+
 
     class MyMappedCollection(MappedCollection):
         """Use @internally_instrumented when your methods
@@ -618,7 +630,8 @@ Iteration will go through ``itervalues()`` unless otherwise decorated.
    of :class:`.MappedCollection` which uses :meth:`.collection.internally_instrumented`
    can be used::
 
-    from sqlalchemy.orm.collections import _instrument_class, MappedCollection
+    from sqlalchemy.orm.collections import MappedCollection, _instrument_class
+
     _instrument_class(MappedCollection)
 
    This will ensure that the :class:`.MappedCollection` has been properly