zoukankan      html  css  js  c++  java
  • sqlalchemy

    orm介绍

    orm英文全称object relational mapping,就是对象映射关系程序,简单来说我们类似python这种面向对象的程序来说一切皆对象,但是我们使用的数据库却都是关系型的,为了保证一致的使用习惯,通过orm将编程语言的对象模型和数据库的关系模型建立映射关系,这样我们在使用编程语言对数据库进行操作的时候可以直接使用编程语言的对象模型进行操作就可以了,而不用直接使用sql语言。

    orm的优点:

    • 隐藏了数据访问细节,“封闭”的通用数据库交互,ORM的核心。他使得我们的通用数据库交互变得简单易行,并且完全不用考虑该死的SQL语句。快速开发,由此而来。
    • ORM使我们构造固化数据结构变得简单易行。

    缺点:

    • 无可避免的,自动化意味着映射和关联管理,代价是牺牲性能(早期,这是所有不喜欢ORM人的共同点)。现在的各种ORM框架都在尝试使用各种方法来减轻这块(LazyLoad,Cache),效果还是很显著的。

    sqlalchemy

    在Python中,最有名的ORM框架是SQLAlchemy。用户包括openstack\Dropbox等知名公司或应用,主要用户列表http://www.sqlalchemy.org/organizations.html#openstack

    sqlalchemy的基本使用

    创建表结构

     1 mport sqlalchemy
     2 from sqlalchemy import create_engine
     3 from sqlalchemy.ext.declarative import declarative_base
     4 from sqlalchemy import Column, Integer, String
     5  
     6 engine = create_engine("mysql+pymysql://root:alex3714@localhost/testdb",
     7                                     encoding='utf-8', echo=True)
     8  
     9  
    10 Base = declarative_base() #生成orm基类
    11  
    12 class User(Base):
    13     __tablename__ = 'user' #表名
    14     id = Column(Integer, primary_key=True)
    15     name = Column(String(32))
    16     password = Column(String(64))
    17  
    18 Base.metadata.create_all(engine) #创建表结构
    View Code

    创建数据

     1 Session_class = sessionmaker(bind=engine) #创建与数据库的会话session class ,注意,这里返回给session的是个class,不是实例
     2 Session = Session_class() #生成session实例
     3  
     4  
     5 user_obj = User(name="alex",password="alex3714") #生成你要创建的数据对象
     6 print(user_obj.name,user_obj.id)  #此时还没创建对象呢,不信你打印一下id发现还是None
     7  
     8 Session.add(user_obj) #把要创建的数据对象添加到这个session里, 一会统一创建
     9 print(user_obj.name,user_obj.id) #此时也依然还没创建
    10  
    11 Session.commit() #现此才统一提交,创建数据
    View Code

    查询

     1 my_user = Session.query(User).filter_by(name="alex").first()
     2 print(my_user)
     3 
     4 #输出
     5 <__main__.User object at 0x105b4ba90>
     6 
     7 print(my_user.id,my_user.name,my_user.password)
     8 
     9 #输出
    10 alex alex3714

    不过刚才上面的显示的内存对象对址你是没办法分清返回的是什么数据的,除非打印具体字段看一下,如果想让它变的可读,只需在定义表的类下面加上这样的代码

    1 def __repr__(self):
    2     return "<User(name='%s',  password='%s')>" % (
    3         self.name, self.password)

    修改

    1 my_user = Session.query(User).filter_by(name="alex").first()
    2  
    3 my_user.name = "Alex Li"
    4  
    5 Session.commit()

    回滚

     1 my_user = Session.query(User).filter_by(id=1).first()
     2 my_user.name = "Jack"
     3  
     4  
     5 fake_user = User(name='Rain', password='12345')
     6 Session.add(fake_user)
     7  
     8 print(Session.query(User).filter(User.name.in_(['Jack','rain'])).all() )  #这时看session里有你刚添加和修改的数据
     9  
    10 Session.rollback() #此时你rollback一下
    11  
    12 print(Session.query(User).filter(User.name.in_(['Jack','rain'])).all() ) #再查就发现刚才添加的数据没有了。
    13  
    14 # Session
    15 # Session.commit()

    获取所有数据

    1 print(Session.query(User.name,User.id).all() )

    多条件查询

    1 objs = Session.query(User).filter(User.id>0).filter(User.id<7).all()

    统计

    Session.query(User).filter(User.name.like("Ra%")).count()

    分组

    from sqlalchemy import func
    print(Session.query(func.count(User.name),User.name).group_by(User.name).all() )

    外键关联

     1 from sqlalchemy import ForeignKey
     2 from sqlalchemy.orm import relationship
     3  
     4 class Address(Base):
     5     __tablename__ = 'addresses'
     6     id = Column(Integer, primary_key=True)
     7     email_address = Column(String(32), nullable=False)
     8     user_id = Column(Integer, ForeignKey('user.id'))
     9  
    10     user = relationship("User", backref="addresses") #这个nb,允许你在user表里通过backref字段反向查出所有它在addresses表里的关联项
    11  
    12     def __repr__(self):
    13         return "<Address(email_address='%s')>" % self.email_address

    创建关联对象

    1 obj = Session.query(User).filter(User.name=='rain').all()[0]
    2 print(obj.addresses)
    3  
    4 obj.addresses = [Address(email_address="r1@126.com"), #添加关联对象
    5                  Address(email_address="r2@126.com")]
    6  
    7  
    8 Session.commit()

    反查

    1 obj = Session.query(User).first()
    2 for i in obj.addresses: #通过user对象反查关联的addresses记录
    3     print(i)
    4  
    5 addr_obj = Session.query(Address).first()
    6 print(addr_obj.user.name)  #在addr_obj里直接查关联的user表

    连表查询

    1 ret=Session.query(User,Address).filter(User.id==Address.id).all()
    2 print(ret)

    多外键关联

     1 from sqlalchemy import Integer, ForeignKey, String, Column
     2 from sqlalchemy.ext.declarative import declarative_base
     3 from sqlalchemy.orm import relationship
     4  
     5 Base = declarative_base()
     6  
     7 class Customer(Base):
     8     __tablename__ = 'customer'
     9     id = Column(Integer, primary_key=True)
    10     name = Column(String)
    11  
    12     billing_address_id = Column(Integer, ForeignKey("address.id"))
    13     shipping_address_id = Column(Integer, ForeignKey("address.id"))
    14  
    15     billing_address = relationship("Address", foreign_keys=[billing_address_id])
    16     shipping_address = relationship("Address", foreign_keys=[shipping_address_id])
    17  
    18 class Address(Base):
    19     __tablename__ = 'address'
    20     id = Column(Integer, primary_key=True)
    21     street = Column(String)
    22     city = Column(String)
    23     state = Column(String)

    多对多关系

    多对多创建

     1 #一本书可以有多个作者,一个作者又可以出版多本书
     2 
     3 
     4 from sqlalchemy import Table, Column, Integer,String,DATE, ForeignKey
     5 from sqlalchemy.orm import relationship
     6 from sqlalchemy.ext.declarative import declarative_base
     7 from sqlalchemy import create_engine
     8 from sqlalchemy.orm import sessionmaker
     9 
    10 
    11 Base = declarative_base()
    12 
    13 book_m2m_author = Table('book_m2m_author', Base.metadata,
    14                         Column('book_id',Integer,ForeignKey('books.id')),
    15                         Column('author_id',Integer,ForeignKey('authors.id')),
    16                         )
    17 
    18 class Book(Base):
    19     __tablename__ = 'books'
    20     id = Column(Integer,primary_key=True)
    21     name = Column(String(64))
    22     pub_date = Column(DATE)
    23     authors = relationship('Author',secondary=book_m2m_author,backref='books')
    24 
    25     def __repr__(self):
    26         return self.name
    27 
    28 class Author(Base):
    29     __tablename__ = 'authors'
    30     id = Column(Integer, primary_key=True)
    31     name = Column(String(32))
    32 
    33     def __repr__(self):
    34         return self.name
    35 
    36 Session_class = sessionmaker(bind=engine) #创建与数据库的会话session class ,注意,这里返回给session的是个class,不是实例
    37 s = Session_class() #生成session实例
    38  
    39 b1 = Book(name="跟Alex学Python")
    40 b2 = Book(name="跟Alex学把妹")
    41 b3 = Book(name="跟Alex学装逼")
    42 b4 = Book(name="跟Alex学开车")
    43  
    44 a1 = Author(name="Alex")
    45 a2 = Author(name="Jack")
    46 a3 = Author(name="Rain")
    47  
    48 b1.authors = [a1,a2]
    49 b2.authors = [a1,a2,a3]
    50  
    51 s.add_all([b1,b2,b3,b4,a1,a2,a3])
    52  
    53 s.commit()
    View Code

    查询数据

    1 print('--------通过书表查关联的作者---------')
    2  
    3 book_obj = s.query(Book).filter_by(name="跟Alex学Python").first()
    4 print(book_obj.name, book_obj.authors)
    5  
    6 print('--------通过作者表查关联的书---------')
    7 author_obj =s.query(Author).filter_by(name="Alex").first()
    8 print(author_obj.name , author_obj.books)
    9 s.commit()

    输出如下:

    1 --------通过书表查关联的作者---------
    2 跟Alex学Python [Alex, Jack]
    3 --------通过作者表查关联的书---------
    4 Alex [跟Alex学把妹, 跟Alex学Python]

    多对多删除

    通过书删除作者

    1 author_obj =s.query(Author).filter_by(name="Jack").first()
    2  
    3 book_obj = s.query(Book).filter_by(name="跟Alex学把妹").first()
    4  
    5 book_obj.authors.remove(author_obj) #从一本书里删除一个作者
    6 s.commit()

    直接删除作者

    1 author_obj =s.query(Author).filter_by(name="Alex").first()
    2 # print(author_obj.name , author_obj.books)
    3 s.delete(author_obj)
    4 s.commit()
  • 相关阅读:
    SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long 解决方法
    Apache Commons 简介
    CSS设置只显示两行文字
    HTML中关于动态创建的标签无法绑定js事件的解决方法:.on()方法的 [.selector]
    AISing Programming Contest 2021(AtCoder Beginner Contest 202)E
    CF620E New Year Tree(dfs序+线段树)
    HDU6955 2021多校 Xor sum(字典树+前缀和异或)
    HDU6959 2021多校 zoto(莫队+分块)
    CF1285D Dr. Evil Underscores(分治)
    CF706D Vasiliy's Multiset(字典树的删除)
  • 原文地址:https://www.cnblogs.com/kxsph/p/9325603.html
Copyright © 2011-2022 走看看