zoukankan      html  css  js  c++  java
  • SQLAlchemy-对象关系教程ORM-create

      ORM是建立在SQL语言构造器之上的工具集,用于将Python对象映射到数据库的行,提供了一系列接口用于从数据库中存取对象(行)。在ORM 工作时,在底层调用SQL语言构造器的API,这些通用的操作有些许的不同。不同的是,你不再使用行,而是使用自定义类的对象来操作。另外,数据库的查询 方式也不同,ORM的可以生成大多数的SQL查询,除此之外还可以在类中定义更多操作

    1)检查sqlalchemy版本

    >>> import sqlalchemy
    >>> sqlalchemy.__version__
    '1.2.0b2'

    2) 建立连接connecting

    >>> from sqlalchemy import create_engine
    >>> engine=create_engine("mysql+pymysql://admin:admin@192.168.6.22/coursesys?charset=utf8",encoding="utf-8",echo=True)
    
        1)通过create_engine()建立连接,create_engine是 Engine实例,create_engine第一次调用的时候会调用Engine.execute()或者 Engine.connect()方法,
        通过dialect在数据库和DBAPI之间建立连接关系。
        注意:返回create_engine对象并没有连接到数据库。只有在执行第一次要求对数据库时才连接
        2)echo是SQLAlchemy logging 是个标准logging模型。当echo 为True看到所有生成的SQL;希望少输出,设置它 False
        3)mysql+pymysql://admin:admin@192.168.6.22/coursesys?charset=utf8 是个dialect连接
        4)engine=create_engine('sqlite:///:memory:',echo=True)将使用一个只在内存中SQLite数据库

    3)声明映射

    我们使用ORM:映射类与数据库表。SQLAlchemy在中首先通过declarative_base申明一个基类。这个基类维持着类与数据库表的关系

    >>> from sqlalchemy.ext.declarative import declarative_base
    >>> Base=declarative_base()
    

      声明表第一种方式:在自定义类继承declarative_base这个基类来映射数据表

      

    >>>  class User(Base):
             __tablename__="users"
             id=Column(Integer,primary_key=True)
             name=Column(String)
             fullname=Column(String)
             password=Column(String)
             def __repr__(self):
                 return "User(name=%s,fullname=%s,password=%s" %(self.name,self.fullname,self.password)
            

      __tablename__指定表名
      Column 指定字段
      primary_key 设置主键
      __repr__ 当打印User对象时显示的数据。
    声明表第二种方式:通过模式声明,通过__table__可以查看定义表元数据。

      

    from sqlalchemy import Table, MetaData, Column, Integer, String, ForeignKey
    from sqlalchemy.orm import mapper
     
    metadata = MetaData()
     
    user = Table('user', metadata,
                Column('id', Integer, primary_key=True),
                Column('name', String(50)),
                Column('fullname', String(50)),
                Column('password', String(12))
            )
     
    class User(object):
        def __init__(self, name, fullname, password):
            self.name = name
            self.fullname = fullname
            self.password = password
     
    mapper(User, user)
    >>> User.__table__
    Table('users', MetaData(bind=None), Column('id', Integer(), table=<users>, prima
    ry_key=True, nullable=False), Column('name', String(), table=<users>), Column('f
    ullname', String(), table=<users>), schema=None)
    MetaData是一个注册表包括能够一组执行的命令到数据库,上面声明了表的类,但是数据库中并没有创建表,
    通过Base.metadata.create_all(engine)向数据库发出建表完成类与表的映射

    4)建立表

    >>Base.metadata.create_all(engine)
    
    2017-08-17 14:51:37,117 INFO sqlalchemy.engine.base.Engine SELECT CAST('test pla
    in returns' AS VARCHAR(60)) AS anon_1
    2017-08-17 14:51:37,117 INFO sqlalchemy.engine.base.Engine ()
    2017-08-17 14:51:37,117 INFO sqlalchemy.engine.base.Engine SELECT CAST('test uni
    code returns' AS VARCHAR(60)) AS anon_1
    2017-08-17 14:51:37,117 INFO sqlalchemy.engine.base.Engine ()
    2017-08-17 14:51:37,133 INFO sqlalchemy.engine.base.Engine PRAGMA table_info("us
    ers")
    2017-08-17 14:51:37,133 INFO sqlalchemy.engine.base.Engine ()
    2017-08-17 14:51:37,133 INFO sqlalchemy.engine.base.Engine
    CREATE TABLE users (
            id INTEGER NOT NULL,
            name VARCHAR,
            fullname VARCHAR,
            PRIMARY KEY (id)
    )
    
    
    2017-08-17 14:51:37,133 INFO sqlalchemy.engine.base.Engine ()
    2017-08-17 14:51:37,133 INFO sqlalchemy.engine.base.Engine COMMIT

    5)字段长度

      在上面的String中我们并没有指明长度,在SQLite和PostgreSQL是有效的,但是在mysql等中String,Integer, Numeric等会报错需要指定长度
      Column(String(50))

      在oracleo等数据库中,有可能需要用到序列,你可以通过Sequence来使用
      from sqlalchemy import Sequence
      Column(Integer, Sequence('user_id_seq'), primary_key=True)

        class User(Base):
        __tablename__ = 'users'
        id = Column(Integer, Sequence('user_id_seq'), primary_key=True)
        name = Column(String(50))
        fullname = Column(String(50))
        password = Column(String(12))
    
        def __repr__(self):
            return "<User(name='%s', fullname='%s', password='%s')>" % (
                                    self.name, self.fullname, self.password)

    6)建立会话

      1)通过 Session处理ORM和数据表。
            两种方式:声明并绑定engine
    >>> from sqlalchemy.orm import sessionmaker
    >>> Session = sessionmaker(bind=engine)
       2) 如果还没有engine,先创建engine,在通过configure绑定到session
        Session = sessionmaker()
        Session.configure(bind=engine)
        上面通过sessionmaker创建是一个类,需要实例类
        session=Session()

    7)增加修改数据

    >>> ed_user=User(name="ed",fullname="ed Jone")
    >>> session.add(ed_user)

     8)获取自曾ID

      

    ed_user.id

     9)查看数据

      

    >>> our_user = session.query(User).filter_by(name='ed').first() 
    >>> our_user
    <User(name='ed', fullname='Ed Jones', password='edspassword'

     10)修改数据

    ed_user.fullname = '11111'

      session.dirty 修改数据后,数据变为脏数据,可以通过dirty查看
      IdentitySet([<User(name='ed', fullname='11111'>])

    11)增加一组数据

    session.add_all([
    ...     User(name='wendy', fullname='Wendy Williams'),
    ...     User(name='mary', fullname='Mary Contrary'),
    ...     User(name='fred', fullname='Fred Flinstone'])
    
    
    session.new  #表示查看新增加的数据
    IdentitySet([<User(name='wendy', fullname='Wendy Williams', password='foobar')>,
    <User(name='mary', fullname='Mary Contrary', password='xxg527')>,
    <User(name='fred', fullname='Fred Flinstone', password='blah')>])

    12) 提交数据回滚数据

    上面的数据并没有在数据库中,需要通过commit()方法把数据提交到数据库中,获取通过rollback回滚数据。
    commit()确认数据

    Session.rollback()回滚数据。
    mysql> select * from users;
    Empty set (0.00 sec)
    
    sesstion.commit()
    
    mysql> select * from users;
    +----+------+----------+----------+
    | id | name | fullname | password |
    +----+------+----------+----------+
    |  1 | shi  | shi jun  | 123456   |
    +----+------+----------+----------+
    1 row in set (0.00 sec)
    # -*- coding:utf-8 -*-
    __author__ = 'shisanjun'

    import sqlalchemy
    from sqlalchemy import Column,Integer,String
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy.orm import sessionmaker

    #创建连接
    engine=sqlalchemy.create_engine("mysql+pymysql://admin:admin@192.168.0.121/test2?charset=utf8",echo=True)

    #声明ORM映射基类
    BASE=declarative_base()

    class User(BASE):
    __tablename__="users" #指定表名
    id=Column(Integer,primary_key=True) #建立主键
    name=Column(String(32))
    fullname=Column(String(32))
    password=Column(String(32))

    def __repr__(self): #返回对象时打印显示
    return "name:%s full name:%s password:%s" %(self.name,self.fullname,self.password)

    #向数据库发出建表,完成类与表的映射,在数据库中生成所有继承declarative_base表
    BASE.metadata.create_all(bind=engine)
    #声明会话类
    Session=sessionmaker(bind=engine)
    #实例化会话类
    session=Session()

    #增加数据
    user1=User(name="ed",fullname="ed jone",password="123456")
    #增加一条数据
    session.add(user1)
    #查看自增ID号
    print(user1.id)
    #增加多条数据
    session.add_all([
    User(name="shi",fullname="shi jone",password="123456"),
    User(name="san",fullname="san jone",password="123456"),
    User(name="jun",fullname="jun jone",password="123456"),
    ])
    #查看新增数据
    print(session.new)

    #修改数据
    user1.fullname="tianshi"

    #查看脏数据
    print(session.dirty)

    #上面的数据并没有提交到数据库中,数据还在内存中

    #把sesstion事务数据提交到数据库中
    session.commit()
    #把数据从session事务中剔除
    #session.rollback()
  • 相关阅读:
    什么?Spring Boot CommandLineRunner 有坑!?
    关于 websocket 跨域的一个奇怪问题…
    电商金额计算的 4 个坑,千万注意了!
    微服务模块划分原则和接口定义原则
    tcp的三次握手(连接)与四次挥手(断开)
    二叉树遍历及算法实现
    elasticsearch搜索 倒排索引
    kubernetes落地-传统web服务迁移
    Docker核心技术-容器管理
    Docker核心技术-镜像管理
  • 原文地址:https://www.cnblogs.com/lixiang1013/p/7382215.html
Copyright © 2011-2022 走看看