zoukankan      html  css  js  c++  java
  • Python 9 sqlalchemy ORM

    一、ORM介绍:

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

    orm的优点:

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

    缺点:

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

    二、sqlalchemy安装

    pip install SQLAlchemy
    pip install pymysql

    连接数据库: MySQL
    -Python mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname> pymysql mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>] MySQL-Connector mysql+mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname> cx_Oracle oracle+cx_oracle://user:pass@host:port/dbname[?key=value&key=value...] 更多详见:http://docs.sqlalchemy.org/en/latest/dialects/index.html

     三、sqlalchemy基本使用

    创建表:

    import sqlalchemy
    from sqlalchemy import create_engine
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import Column,Integer,String
    
    engine = create_engine('mysql+pymysql://cheng:123456@192.168.71.3/test_cheng',
                           encoding = 'utf-8',echo=True)
    
    Base = declarative_base()  #生成基类
    
    class User(Base):
        __tablename__ = 'user'  #表名
        id = Column(Integer,primary_key=True)
        name = Column(String(32))
        password = Column(String(64))
    
    Base.metadata.create_all(engine)  #创建表结构

    插入数据:

    import sqlalchemy
    from sqlalchemy import create_engine
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import Column,Integer,String
    from sqlalchemy.orm import sessionmaker
    
    engine = create_engine('mysql+pymysql://cheng:123456@192.168.71.3/test_cheng',
                           encoding = 'utf-8',echo=True)
    
    Base = declarative_base()
    
    class User(Base):
        __tablename__ = 'user'
        id = Column(Integer,primary_key=True)
        name = Column(String(32))
        password = Column(String(64))
    
    Session_class = sessionmaker(bind=engine)
    Session = Session_class()
    for i in range(10):
        user_obj = User(name='cheng%s'%i,password='%s*321'%i)
        Session.add(user_obj)
        
    Session.commit()

    查询和修改数据:

    import sqlalchemy
    from sqlalchemy import create_engine
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import Column,Integer,String
    from sqlalchemy.orm import sessionmaker
    
    engine = create_engine('mysql+pymysql://cheng:123456@192.168.71.3/test_cheng',
                           encoding = 'utf-8')
    
    Base = declarative_base()
    
    class User(Base):
        __tablename__ = 'user'
        id = Column(Integer,primary_key=True)
        name = Column(String(32))
        password = Column(String(64))
    
    Session_class = sessionmaker(bind=engine)
    Session = Session_class()
    #1.first生成一个实例,而all生成一个实例列表:
    my_user = Session.query(User).filter_by(name='cheng77').first()
    print(my_user.id,my_user.name,my_user.password)
    
    my_user = Session.query(User).filter_by(name = 'cheng78').all()
    for i in my_user:
        print(i.id,i.name,i.password)
    
    #2.filter_by不支持<,>,==,而filter支持<,>,==而且filter支持多条件查询:
    my_user = Session.query(User).filter(User.id < 29).filter(User.id > 13).all()
    for i in my_user:
        print(i.id,i.name,i.password)
    
    #3.修改数据:
    my_user = Session.query(User).filter_by(name='cheng77').first()
    my_user.name = 'cheng77777'
    Session.commit()
    print(my_user.id,my_user.name,my_user.password)
    
    #4.回滚:
    <----插入数据---->
    Session.rollback()
    <----查询数据没有插入---->
    
    #5.统计和分组:
    conn = Session.query(User).filter(User.name.like('ch%')).count()
    print(conn)
    
    from sqlalchemy import func
    list_group = Session.query(func.count(User.name),User.name).group_by(User.name).all()
    for i in list_group:
        print(i)
    
    #6.将查询的数据可读:
      def __repr__(self):
          return "<User(name='%s', password='%s')>" % (self.name, self.password)    #在User类里添加
     my_user = Session.query(User.name,User.password).all()
     print(my_user)

     外键关联:

    from sqlalchemy import create_engine
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import Column,String,Integer,ForeignKey,DATE
    from sqlalchemy.orm import sessionmaker,relationship
    from sqlalchemy import func
    engine = create_engine('mysql+pymysql://cheng:123456@192.168.71.3/test_cheng',
                           encoding = 'utf-8')
    
    
    Base = declarative_base()
    class Student(Base):
        __tablename__ = 'student'
        id = Column(Integer,primary_key=True)
        name = Column(String(32),nullable=False)
        data = Column(DATE,nullable=False)
    
        def __repr__(self):
            return 'id:%s,name:%s'%(self.id,self.name)
    
    class Study_record(Base):
        __tablename__ = 'study_record'
        id = Column(Integer,primary_key=True)
        day = Column(Integer,nullable=False)
        status = Column(String(32),nullable=False)
        stu_id = Column(Integer,ForeignKey('student.id'))    #创建外键关联
    
        student = relationship('Student',backref='my_study_record')  #允许你在student表里通过backref字段反向查出study_record表里的字段。
        def __repr__(self):
            #return 'id:%s,day:%s,stu_id:%s'%(self.id,self.day,self.stu_id)
            return 'id:%s,day:%s,stu_id:%s' % (self.id, self.day, self.student.name)    #通过self.student.name调出student表里name字段的值。
    Base.metadata.create_all(engine)
    
    Session_class = sessionmaker(bind=engine)
    Session = Session_class()
    data = Session.query(Student).filter(Student.name=='cheng').first()   #查出name等于cheng的学生,再打印出Study_record类里repr的返回值。
    print(data.my_study_record)
    
    
    # stu_obj = Student(name='cheng1',data = '2017-11-01')
    # record_obj = Study_record(day=2,status ='yes',stu_id=3)  #插入数据时先创建student表里的主键,在创建study_record的外键,因为有外键约束
    # Session.add_all([record_obj])
    # Session.commit()

     多外键关联:

    from sqlalchemy import create_engine
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import Column,String,Integer,ForeignKey,DATE
    from sqlalchemy.orm import sessionmaker,relationship
    engine = create_engine('mysql+pymysql://cheng:123456@192.168.71.3/test_cheng?charset=utf8',
                           encoding='utf-8')
    
    Base = declarative_base()
    
    class Customer(Base):
        __tablename__ = 'customer'
        id = Column(Integer, primary_key=True)
        name = Column(String(32))
        billing_address_id = Column(Integer, ForeignKey("address.id"))
        shipping_address_id = Column(Integer, ForeignKey("address.id"))
    
        billing_address = relationship("Address", foreign_keys=[billing_address_id])
        shipping_address = relationship("Address", foreign_keys=[shipping_address_id])
    
    class Address(Base):
        __tablename__ = 'address'
        id = Column(Integer, primary_key=True)
        street = Column(String(32))
        city = Column(String(32))
        state = Column(String(32))
    Base.metadata.create_all(engine)
    
    Session_class = sessionmaker(bind=engine)
    Session = Session_class()
    #address_obj = Address(street ='tongzhou1',city ='beijing2',state='beijing3')
    address_obj = Address(street ='通州',city ='北京',state='北京')
    Session.add_all([address_obj])
    customer_obj = Customer(name='chengll',billing_address=address_obj,shipping_address=address_obj)   #通过以上关联,可以这样进行赋值
    Session.add_all([customer_obj])
    Session.commit()

     多对多:

    from sqlalchemy import Table, Column, Integer,String,DATE, ForeignKey
    from sqlalchemy.orm import relationship
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import create_engine
    from sqlalchemy.orm import sessionmaker
    
    engine = create_engine('mysql+pymysql://root:ccc949885111@192.168.71.3/cuichao?charset=utf8',encoding='utf-8')
    Base = declarative_base()
    
    book_m2m_author = Table('book_m2m_author', Base.metadata,
                            Column('book_id',Integer,ForeignKey('books.id')),
                            Column('author_id',Integer,ForeignKey('authors.id')),
                            )
    class Book(Base):
        __tablename__ = 'books'
        id = Column(Integer,primary_key=True)
        name = Column(String(64))
        pub_date = Column(DATE)
        authors = relationship('Author',secondary=book_m2m_author,backref='books')
        def __repr__(self):
            return self.name
    
    class Author(Base):
        __tablename__ = 'authors'
        id = Column(Integer, primary_key=True)
        name = Column(String(32))
        def __repr__(self):
            return self.name
    Base.metadata.create_all(engine)
    
    Session_class = sessionmaker(bind=engine)  # 创建与数据库的会话session class ,注意,这里返回给session的是个class,不是实例
    s = Session_class()  # 生成session实例
    
    b1 = Book(name="跟Alex学Python")
    b2 = Book(name="跟Alex学把妹")
    b3 = Book(name="跟Alex学装逼")
    b4 = Book(name="跟Alex学开车")
    
    a1 = Author(name="Alex")
    a2 = Author(name="Jack")
    a3 = Author(name="Rain")
    
    b1.authors = [a1, a2]
    b2.authors = [a1, a2, a3]
    
    s.add_all([b1, b2, b3, b4, a1, a2, a3])
    
    s.commit()
    # print('--------通过书表查关联的作者---------')
    #
    # book_obj = s.query(Book).filter_by(name="跟Alex学Python").first()
    # print(book_obj.name, book_obj.authors)
    #
    # print('--------通过作者表查关联的书---------')
    # author_obj = s.query(Author).filter_by(name="Alex").first()
    # print(author_obj.name, author_obj.books)
    # s.commit()
  • 相关阅读:
    pandas分组聚合基本操作
    微信开发系列----01:成为开发者
    未能加载文件或程序集“System.Web.Http.WebHost, Version=4.0.0.0, ”或它的某一个依赖项。系统找不到指定的文件。
    ADO.NET基础巩固-----连接类和非连接类
    ADO.NET封装的SqlHelper
    Jmeter + Grafana + InfluxDB 性能测试监控
    性能测试监控:Jmeter+Collectd+Influxdb+Grafana
    性能测试总结(一)---基础理论篇
    地铁模型分析性能测试
    JIRA问题状态已关闭,但是解决结果还是未解决
  • 原文地址:https://www.cnblogs.com/chimeiwangliang/p/7269102.html
Copyright © 2011-2022 走看看