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’)])

 

 

待续...

posted @ 2016-05-19 17:12  赵洪  阅读(338)  评论(0编辑  收藏  举报