SQLAlchemy using notes--sqlalchemy ORM (ii)

Source: Internet
Author: User
Tags aliases stmt

Reference:
Http://docs.sqlalchemy.org/en/rel_1_0/orm/tutorial.html#building-a-relationship
Http://docs.sqlalchemy.org/en/rel_1_0/orm/tutorial.html#working-with-related-objects

Establish a relationship between tables to build out

Add a user's foreign key to address

 fromSQLAlchemy Import ForeignKey, Column, String, Integer fromSqlalchemy.orm Import Relationshipclass User(Base): __tablename__ = ' users ' id =Column(Integer, primary_key=True)Name =Column(String)FullName =Column(String)Password =Column(String)class Address(Base): __tablename__ = ' addresses ' id =Column(Integer, primary_key=True)Email_address =Column(String, nullable=False)USER_ID =Column(Integer, foreignkey('users.  Id ')) user = Relationship('User', backref=backref('addresses ', order_by=ID) )

The Backref parameter usage form in relationship:

backref="addresses"#直接使用表名的字符串backref=backref(‘addresses‘#使用backref函数backref=backref(‘addresses‘#brackref函数可以添加参数,详见http://docs.sqlalchemy.org/en/rel_1_0/orm/backref.html#backref-arguments

You can use user.addresses to get address from user and use address.users address to get user

Backref will add a relationship between user and address, which is essentially:

From SQLAlchemy ImportInteger, ForeignKey,String,ColumnFrom sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy.orm Import relationshipbase = Declarative_base ( ) class User (Base): __tablename__ =' user 'ID =Column(Integer, primary_key=True) name =Column(String) addresses = relationship ("Address", back_populates="User") class Address (Base): __tablename__ =' Address 'ID =Column(Integer, primary_key=True) Email =Column(String) user_id =Column(Integer, ForeignKey (' User.ID ')) user = relationship ("User", back_populates="Addresses")

Relationship in the

Add to
>>> jack.addresses = [...                 Address(email_address=‘[email protected]‘),...                 Address(email_address=‘[email protected]‘)]
Get
>>> jack.addresses[1]<Address(email_address=‘[email protected]‘)>>>> jack.addresses[1].user<User(name=‘jack‘, fullname=‘Jack Bean‘, password=‘gjffdd‘)>
Commit
session.add(jack)session.commit()

Address is automatically added

One to many relationship
class Parent(Base):    ‘parent‘    Column(Integer, primary_key=True)    children = relationship("Child", backref="parent")class Child(Base):    ‘child‘    Column(Integer, primary_key=True)    Column(Integer, ForeignKey(‘parent.id‘))


Many to one relationship
class Parent(Base):    ‘parent‘    Column(Integer, primary_key=True)    Column(Integer, ForeignKey(‘child.id‘))    child = relationship("Child", backref="parents")class Child(Base):    ‘child‘    Column(Integer, primary_key=True)


One to one relationship
from sqlalchemy.orm import backrefclass Parent(Base): __tablename__ = ‘parent‘ id = Column(Integer, primary_key=True) child_id = Column(Integer, ForeignKey(‘child.id‘)) child = relationship("Child", backref=backref("parent", uselist=False))class Child(Base): __tablename__ = ‘child‘ id = Column(Integer, primary_key=True)


Many to many relationship

Need an intermediate table and add secondary parameter in Relatonship

Association_table =Table(' Association ', Base.metadata,Column(' left_id ',Integer, ForeignKey (' Left.id ')),Column(' right_id ',Integer, ForeignKey (' Right.id '))) class Parent (Base): __tablename__ =' left 'ID =Column(Integer, primary_key=True) Children = Relationship ("Child", Secondary=association_table, backref="Parents") class Child (Base): __tablename__ =' right 'ID =Column(Integer, primary_key=True)

This way, when the child is added to delete parent or parent add Delete child, you do not need to work on the intermediate table, add delete directly.

parent.children.append(child)child.parents.append(parent)

You can also use a class to create an intermediate table so that you can save some additional information in the intermediate table. But you can't do it the same way as before. The intermediate table is automatically manipulated.

Class Association (Base): __tablename__ =' Association 'left_id =Column(Integer, ForeignKey (' Left.id '), primary_key=True) right_id =Column(Integer, ForeignKey (' Right.id '), primary_key=True) Extra_data =Column(String( -) Child = Relationship ("Child", back_populates="Parents") Parent = Relationship ("Parent", back_populates="Children") class Parent (Base): __tablename__ =' left 'ID =Column(Integer, primary_key=True) Children = Relationship ("Association", back_populates="Parent") class Child (Base): __tablename__ =' right 'ID =Column(Integer, primary_key=True) Parents = Relationship ("Association", back_populates="Child")


Join operation

You can use Query.join ()

>>> session.query(User).join(Address)....         filter(Address.email_address==‘[email protected]‘)....         all()[<User(name=‘jack‘, fullname=‘Jack Bean‘, password=‘gjffdd‘)>]

You can use join directly on user because there is only one outside of user and Address, other join forms:

query.join(Address, User.id==Address.user_id)    explicit conditionquery.join(User.addresses)                       lefttorightquery.join(Address, User.addresses)              withexplicit targetquery.join(‘addresses‘)                          # same, using a string

Using external links

query.outerjoin(User.addresses)   # 默认是左外连接。

When multiple entity points are used in query, use the join default join to chase the left side,
For example:

query = session.query(User, Address).join# 报错query = session.query(Address, User).join# 正确

If you want to customize the table using join, you can use the Select_form

query = Session.query(User, Address).select_from(Address).join(User)


Alias aliases

If you want to join yourself, you can use aliases

from sqlalchemy.orm import aliasedadalias1 = aliased(Address)adalias2 = aliased(Address)forin     session.query(User.name, adalias1.email_address, adalias2.email_address).    join(adalias1, User.addresses).    join(adalias2, User.addresses).    filter(adalias1.email_address==‘[email protected]‘).    filter(adalias2.email_address==‘[email protected]‘):    print(username, email1, email2)


Working with sub-queries

See examples of official documents directly:

>>> from sqlalchemy.sql import func>>> stmt = Session.query (address.user_id, Func.count (' * ')....Label' Address_count '))....Group_by (address.user_id). Subquery () >>> forU, CountinchSession.query (User, Stmt.c.address_count)....Outerjoin (stmt, user.id==stmt.c.user_id). Order_by (user.id):...Print (U, count) <user (name=' Ed ', fullname=' Ed Jones ', password=' F8s7ccs ') > None<user (name=' Wendy ', fullname=' Wendy Williams ', password=' Foobar ') > None<user (name=' Mary ', fullname=' Mary contrary ', password=' xxg527 ') > None<user (name=' Fred ', fullname=' Fred flinstone ', password=' blah ') > None<user (name=' Jack ', fullname=' Jack Bean ', password=' GJFFDD ') >2


Using exists

See examples of official documents:

forin session.query(User.name).filter(stmt):...     print(name)jack

Equivalent to:

forin session.query(User.name)....         filter(User.addresses.any()):...     print(name)jack

User.addresses can use = =,! =, any, and so on in the filter like other properties in user.

query. Filter  (Address.user = = someuser) query. filter  (Address.user! = someuser) query. filter  (Address.user = = None) query. filter  (user.addresses. contains  (someaddress)) Query. filter  (user.addresses. any  (address.email_address = =  ' bar ' )) # also takes keyword arguments:  query. filter  (user.addresses. any  (Email_address= ' bar ' )) Query. filter  (Address.user.has (Name= ' Ed ' )] Session.query (Address) with_parent (Someuser, Span class= "hljs-string" > ' addresses ' )  

SQLAlchemy using notes--sqlalchemy ORM (ii)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.