zoukankan      html  css  js  c++  java
  • Python自动化开发从浅入深-进阶(sqlalchemy)

      SQLAlchemy SQL工具包和对象关系映射(ORM)是面向数据库和Python较全面的一组工具。它包含一些功能,这些功能即可以单独使用也可以结合起来使用,其主要元素依照层次关系相互依赖,如图:

      

         SQLAlchemy 两个最重要的前端部分是Object Relational Mapper(ORM)和SQL Expression Language . SQL Expression可以使用独立的ORM. 当使用ORM的时候,SQL Expression Language保留面向API的公共部分来作为在对象关系配置和查询中使用。

          SQLAlchemy是python下的一款ORM框架,该框架建立在数据库API之上,使用关系对象映射进行数据库操作,简言之便是:将对象转换成SQL,然后使用数据API执行SQL并获取执行结果。

      SQLAlchemy Object Relational Mapper 提供了一种方法,就是让用户定义的python类和数据库表关联起来,这些类对象实例对应表中的行(记录)。在对象实例和他们关联的行之间(称之为工作单元)包含了一个系统,它透明地同步所有状态的改变。也是这样的系统,在用户定义类和相互之间的关系期间表示数据库查询。

      ORM是在SQLAlchemy Expression Language之上进行构造的。SQL Expression Language提供了直接的、原始构造关系数据库方法,ORM则提供了高级的和抽象的模型使用方法,它本身就是Expression Language的一个例子。

        SQLAlchemy目前支持python 2.6以上的版本。

      安装方法

      通过 pip 进行安装:

         pip install SQLAlchemy

      通过python的setup.py安装:

          python setup.py install

      SQLalchemy需要特定数据库的DB-API,根据你要操作的数据库,可以选择不同的DB-API库,比如:oracle需要安装cx_oracle。

      Dialect用于和数据API进行交流,根据配置文件的不同调用不同的数据库API,从而实现对数据库的操作,如:

    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

      >>>sqlalchemy.__version__

     上述简要地描述了SQLAlchemy,下面通过实例进行讲解:

      注意:所有实例均以SQLite数据库为对象

      1、用create_engine建立一个数据库链接,通过MetaData()实例创建users数据库表。    

    >>> from sqlalchemy import create_engine
    
    >>> engine=create_engine('sqlite:///:memory:',echo=True)  #echo标志为True则会利用python标准logging模块输入产生的SQL过程。
    
    >>> from sqlalchemy import Table,Column,Integer,String,MetaData,ForeignKey
    >>> metadata=MetaData()
    >>> users_table=Table('users',metadata,
              Column('id',Integer,primary_key=True),
              Column('name',String),
              Column('fullname',String),
              Column('password',String)
              )

    >>> metadata.create_all(engine)  #通过create_all在数据库中创建users表
    2009-08-26 16:06:02,812 INFO sqlalchemy.engine.base.Engine.0x...bbb0 PRAGMA table_info("users")
    2009-08-26 16:06:02,828 INFO sqlalchemy.engine.base.Engine.0x...bbb0 ()
    2009-08-26 16:06:02,842 INFO sqlalchemy.engine.base.Engine.0x...bbb0 
    CREATE TABLE users (
        id INTEGER NOT NULL, 
        name VARCHAR, 
        fullname VARCHAR, 
        password VARCHAR, 
        PRIMARY KEY (id)
    )

    
    

    2009-08-26 16:06:02,858 INFO sqlalchemy.engine.base.Engine.0x...bbb0 ()
    2009-08-26 16:06:02,875 INFO sqlalchemy.engine.base.Engine.0x...bbb0 COMMIT

    
    

     2、Table对象定义了数据库的表信息,但没有定义行为,可以创建一个类来定义行为,这个类是object的子类,类中定义了__init__和__repr__两个方法,这两个方法是可选的,

    SQLAlchemy从不直接调用__init__()。

    class User(object):
        def __init__(self,name,fullname,password):
            self.name=name
            self.fullname=fullname
            self.password=password
        def __repr__(self):
            return "<User('%s','%s','%s')>" % (self.name,self.fullname,self.password)

     3、mapper创建了一个mapper对象,它将User和users_table进行映射关联。

    >>> mapper(User,users_table)
    <Mapper at 0x13b4250; User>

    4、下面代码测试了User类,在该类的__init__()方法中没有定义id属性,但id列已经存在于users_table对象,通常情况下mapper会为Table中的所有列创建类属性。

    >>> ed_user=User('ed','Ed Jones','edspassword')
    >>> ed_user.name
    'ed'
    >>> ed_user.password
    'edspassword'
    >>> str(ed_user.id)
    'None'

    5、前面的代码分别建立了Table,Class和Mapper,也可以在一次声明中创建它们

    from sqlalchemy import Table,Column,Integer,String,MetaData,ForeignKey
    from sqlalchemy.ext.declarative import declarative_base
    Base=declarative_base()   #基类
    class User(Base):
        __tablename__='users'   #表名
     
        id=Column(Integer,primary_key=True)
        name=Column(String)
        fullname=Column(String)
        password=Column(String)
        def __init__(self,name,fullname,password):
            self.name=name
            self.fullname=fullname
            self.password=password
        def __repr__(self):
            return "<User('%s','%s','%s')>" % (self.name,self.fullname,self.password)
    users_table=User.__table__  #用来获得Table
    metadata=Base.metadata  #获得MetaDATA
    
    创建Session并绑定一个数据库链接
    from sqlalchemy.orm import sessionmaker
    Session=sessionmaker(bind=engine)
     
    如果没有数据库链接,可以这样创建session
    Session=sessionmaker()
     
    当后来由数据库链接后可以这样绑定
    Session.configure(bind=engine)

    通过session的add方法添加一个对象
    >>> ed_user = User(’ed’, ’Ed Jones’, ’edspassword’)
    >>> session.add(ed_user)

    使用session来查询刚才创建的记录

    >>> our_user = session.query(User).filter_by(name=’ed’).first()
    BEGIN
    INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)
    [’ed’, ’Ed Jones’, ’edspassword’]
    SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS user_password
    FROM users
    WHERE users.name = ?
    LIMIT 1 OFFSET 0
    [’ed’]

    >>> our_user
    <User(’ed’,’Ed Jones’, ’edspassword’)>

    使用session的add_all方法添加多个记录

    >>> session.add_all([
    ... User(’wendy’, ’Wendy Williams’, ’foobar’),
    ... User(’mary’, ’Mary Contrary’, ’xxg527’),
    ... User(’fred’, ’Fred Flinstone’, ’blah’)])

     

    待续...

  • 相关阅读:
    Java必会之多线程
    第一周JVM核心技术-工具与GC策略
    JVM核心技术(第一篇)
    SpringCloudAlibaba使用seata做分布式事务
    Go中的interface(接口)
    快排与堆排
    优先队列原来不难!带你手写一个
    【LeetCode】557. 反转字符串中的单词 III
    【LeetCode】214. 最短回文串
    【LeetCode】17. 电话号码的字母组合(回溯)
  • 原文地址:https://www.cnblogs.com/whiggzhaohong/p/5427318.html
Copyright © 2011-2022 走看看