SQLAlchemy using notes--sqlalchemy ORM (ii)

Source: Internet
Author: User
Tags aliases stmt

References:
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 foreign key to user in 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) )

Relationship Backref in the form of use:

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

Ability to 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

Join
>>> 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 will join the initiative itself.

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 join secondary 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 eliminates the need to manipulate the intermediate table when a child is added to delete parent or parent to delete child. Simply add and delete to it.

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

You can also use a class to create an intermediate table, which allows you to save some other information in the intermediate table. But you don't want to be the same as before. Take the initiative to manipulate the intermediate table.

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

Ability to 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 (address) because there is only one built-in between 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,
Like what:

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

Suppose you want to customize the table using join. Ability to use 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

Look directly at the official documentation sample:

>>> 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

Look at an official document sample:

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.