一、写在前面

这篇文章主要介绍了Python的SQLAlchemy框架使用入门,SQLAlchemy框架是Python中用来操作数据库的ORM框架之一,学习过程中主要参考网上现有资料,整理成笔记以便后续自己查阅。  
如果转载,请保留作者信息。  
邮箱地址:jpzhang.ht@gmail.com  
SQLAlchemy: http://www.sqlalchemy.org/ 
中文参考:https://github.com/lzjun567/note/blob/master/note/python/sqlalchemy.md

二、简介

SQLAlchemy的是Python的SQL工具包和对象关系映射,给应用程序开发者提供SQL的强大功能和灵活性。它提供了一套完整的企业级的持久性模式,专为高效率和高性能的数据库访问,改编成简单的Python的领域语言。 
SQLAlchemy是Python界的ORM(Object Relational Mapper)框架,它两个主要的组件: SQLAlchemy ORM 和 SQLAlchemy Core 。 

二、安装

pip install SQLAlchemy
检查安装是否成功:
>>> import sqlalchemy
>>> sqlalchemy.__version__
>>> '1.0.12'
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

三、连接

连接MySQL数据库(需要MySQLdb支持):

from sqlalchemy import create_engine
DB_CONNECT_STRING = 'mysql+mysqldb://root:password@localhost/test?charset=utf8'
engine = create_engine(DB_CONNECT_STRING,echo=True)
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

create_engine方法返回一个Engine实例,Engine实例只有直到触发数据库事件时才真正去连接数据库。 
echo参数是设置 SQLAlchemy 日志记录,这通过 Python 的标准logging模块的快捷方式。启用它,我们会看到产生的所有生成的 SQL,sqlalchemy与数据库通信的命令都将打印出来,例如执行:

engine.execute("select 1").scalar()
  • 1
  • 1

执行打印信息:

2016-02-28 23:55:37,544 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'sql_mode'
2016-02-28 23:55:37,544 INFO sqlalchemy.engine.base.Engine ()
2016-02-28 23:55:37,545 INFO sqlalchemy.engine.base.Engine SELECT DATABASE()
2016-02-28 23:55:37,546 INFO sqlalchemy.engine.base.Engine ()
......
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

四、声明一个映射(declare a Mapping)

declarative_base类维持了一个从类到表的关系,通常一个应用使用一个base实例,所有实体类都应该继承此类对象

from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
  • 1
  • 2
  • 1
  • 2

定义映射的表,表名称、 数据类型的列,在这里定义一个User类:

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from sqlalchemy import create_engineDB_CONNECT_STRING = 'mysql+mysqldb://root:hengtian@localhost/test?charset=utf8'
engine = create_engine(DB_CONNECT_STRING,echo=True)Base = declarative_base()class User(Base):__tablename__ = 'users'id = Column(Integer,primary_key=True)name = Column(String(10))fullname = Column(String(20))password = Column(String(20)) #可以设定长度def __init__(self,name,fullname,password):self.name = nameself.fullname = fullnameself.password = passworddef __repr(self):return "<User('%s','%s','%s')>"%(self.name,self.fullname,self.password)Base.metadata.create_all(engine)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

类使用声明式至少需要一个tablename属性定义数据库表名字,并至少一Column是主键。User类定义一个repr()方法,但请注意,是可选; 
sqlalchemy 就是把Base子类转变为数据库表,定义好User类后,会生成Table和mapper(),分别通过User.table 和User.mapper返回这两个对象,对于主键,象oracle没有自增长的主键时,要使用:

from sqlalchemy import Sequence
Column(Integer,Sequence('user_idseq'),prmary_key=True)
  • 1
  • 2
  • 1
  • 2

数据表字段长度定义:

Column(String(50))
  • 1
  • 1

Base.metadata返回sqlalchemy.schema.MetaData对象,它是所有Table对象的集合,调用create_all()该对象会触发CREATE TABLE语句,如果数据库还不存在这些表的话。

>>> Base.metadata.create_all(engine)
>>> CREATE TABLE users (id INTEGER NOT NULL AUTO_INCREMENT, name VARCHAR(10), fullname VARCHAR(20), password VARCHAR(20), PRIMARY KEY (id)
)
2016-02-29 22:52:03,260 INFO sqlalchemy.engine.base.Engine ()
2016-02-29 22:52:03,350 INFO sqlalchemy.engine.base.Engine COMMIT
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

创建一个User类:

ed_user = User(name='ed', fullname='Ed Jones', password='edspassword')
print ed_user.name
print ed_user.password
print str(ed_user.id)输出:
>>>ed
>>>edspassword
>>>None
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

五、创建Session

Session 使用 connection发送query,把返回的result row 填充到一个object中,该对象同时还会保存在Session中,Session内部有一个叫 Identity Map的数据结构,为每一个对象维持了唯一的副本。primary key 作为 key ,value就是该object。session刚开始无状态,直到有query发起时。对象的变化会被session的跟踪维持着,在数据库做下一次查询后者当前的事务已经提交了时,it fushed all pendings changes to the database. 
这就是传说中的 Unit of work 模式 
例如:

def unit_of_work():session = Session()album = session.query(Album).get(4)album.name = "jun"   #这里不会修改album的name属性,不会触发update语句def unit_of_work():session = Session()album = session.query(Album).get(4)album.name = "jun"   #这里修改了album的name属性,会触发一个update语句session.query(Artist).get(11)session.commit()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

构造了session,何时commit,何时close:

规则:始终保持session与function和objecct分离

对象的四种状态:

⚠注意:对象实例有四种状态,分别是: 
Transient(瞬时的):实例还不在session中,还没有保存到数据库中去,没有数据库身份,像刚创建出来的对象比如User(),仅仅只有mapper()与之关联. 
Pending(挂起的):调用session.add()后,Transient对象就会变成Pending,这个时候它还是不会保存到数据库中,只有等到触发了flush动作才会存在数据库,比如query操作就可以出发flush。同样这个时候的实例的主键一样为None 
Persistent(持久的):session中,数据库中都有对应的一条记录存在,主键有值了。 
Detached(游离的):数据库中有记录,但是session中不存在,对这个状态的对象进行操作时,不会触发任何SQL语句。

Session什么时候清理缓存:

commit()方法调用的时候 
查询时会清理缓存,保证查询结果能反映对象的最新状态 
显示调用session的flush方法 
Session是真正与数据库通信的handler,你还可以把他理解一个容器,add就是往容器中添加对象 
执行完add方法后,ed_user对象处于pending状态,不会触发INSERT语句,当然ed_uesr.id也为None,如果在add方后有查询(session.query),那么会flush一下,把数据刷一遍,把所有的pending信息先flush再执行query。

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)
  • 1
  • 2
  • 1
  • 2

这个定制的Session类将创建新的Session对象绑定到我们的数据库。 
无论何时你需要与数据库连接,你实例化一个Session:

session = Session()
  • 1
  • 1

上述Session是与我们Mysql连接启用的Engine,但它还没有打开任何连接。它第一次使用时,由维护的连接池检索连接,并获取不放,直到我们提交所有更改和/或关闭会话对象才会释放掉。

添加User对象到我们定义的session上,

ed_user = User(name='ed', fullname='Ed Jones', password='edspassword')
session.add(ed_user)
  • 1
  • 2
  • 1
  • 2

添加多个的User对象,使用add_all() :

session.add_all([
User(name='wendy', fullname='Wendy Williams', password='foobar'),
User(name='mary', fullname='Mary Contrary', password='xxg527'),
User(name='fred', fullname='Fred Flinstone', password='blah')])
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

提交事务:

session.commit()
  • 1
  • 1

commit()刷新任何剩余的变化保持到数据库中,并将提交的事务。

回滚:

由于Session工作在一个事务内,我们可以回滚所做过的更改。

session.rollback()
  • 1
  • 1

查询:

在Session上使用query()方法,创建了一个Query对象。此函数接受数目可变的参数,可以是任意组合的类和类表的描述符 
Query对象通过Session.query获取,query接收类或属性参数,以及多个类


>>> for instance in session.query(User).order_by(User.id):
...     print(instance.name, instance.fullname)
ed Ed Jones
wendy Wendy Williams
mary Mary Contrary
fred Fred FlinstoneQuery还接受 ORM 检测描述符作为参数,参数返回的结果被表示为元组:>>> for name, fullname in session.query(User.name, User.fullname):
...     print(name, fullname)
ed Ed Jones
wendy Wendy Williams
mary Mary Contrary
fred Fred Flinstone由Query返回的元组是命名的元组,提供的KeyedTuple类,并可以像普通的 Python 对象多处理。名称是相同的属性,该属性的名称和类的类名:>>> for row in session.query(User, User.name).all():
...    print(row.User, row.name)
<User(name='ed', fullname='Ed Jones', password='f8s7ccs')> ed
<User(name='wendy', fullname='Wendy Williams', password='foobar')> wendy
<User(name='mary', fullname='Mary Contrary', password='xxg527')> mary
<User(name='fred', fullname='Fred Flinstone', password='blah')> fred
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

筛选:

filter_by() 它使用关键字参数:

>>> for name, in session.query(User.name).\
...             filter_by(fullname='Ed Jones'):
...    print(name)
ed
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

filter_by接收的参数形式是关键字参数,而filter接收的参数是更加灵活的SQL表达式结构:

sqlalchemy源码对filter_by的定义
def filter_by(self, **kwargs):
举例:
for user in session.query(User).filter_by(name=’ed’).all():print userfor user in session.query(User).filter(User.name==”ed”).all():print user
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

常用过滤操作:

  • equals:
query.filter(User.name == 'ed')
  • 1
  • 2
  • 1
  • 2
  • not equal:
query.filter(User.name !='ed')
  • 1
  • 1
  • LIKE:
query.filter(User.name.like('%d%')
  • 1
  • 1
  • IN:
query.filter(User.name.in_(['a','b','c'])
  • 1
  • 1
  • NOT IN:
query.filter(~User.name.in_(['ed','x'])
  • 1
  • 1
  • IS NULL:
filter(User.name==None)
  • 1
  • 1
  • IS NOT NULL:
filter(User.name!=None)
  • 1
  • 1
  • AND:
from sqlalchemy import and_
filter(and_(User.name == 'ed',User.fullname=='xxx'))    
  • 1
  • 2
  • 1
  • 2

或者多次调用filter或filter_by

filter(User.name =='ed').filter(User.fullname=='xx')
  • 1
  • 1

还可以是:

query.filter(User.name == ‘ed’, User.fullname == ‘Ed Jones’)
  • 1
  • 1
  • OR:
from sqlalchemy import or_
query.filter(or_(User.name == ‘ed’, User.name == ‘wendy’))
  • 1
  • 2
  • 1
  • 2

查询返回结果:

  • query.all(): all()返回列表
  • query.first(): 返回第一个元素
  • query.one(): 有且只有一个元素时才正确返回。

此外,filter函数还可以接收text对象,text是SQL查询语句的字面对象,比如:

for user in session.query(User).filter(text(“id<224”)).order_by(text(“id”)).all():print user.name
  • 1
  • 2
  • 1
  • 2

count:

有两种count,第一种是纯粹是执行SQL语句后返回有多少行,对应的函数count(),第二个是func.count(),适用在分组统计,比如按性别分组时,男的有多少,女的多少:

session.query(User).filter(User.name==’ed’).count()
session.query(func.count(), User.name).group_by(User.name).all( )
  • 1
  • 2
  • 1
  • 2

六、Building a Relationship

SQLAlchemy中的映射关系有四种,分别是一对多,多对一,一对一,多对多

一对多(one to many):

因为外键(ForeignKey)始终定义在多的一方.如果relationship定义在多的一方,那就是多对一,一对多与多对一的区别在于其关联(relationship)的属性在多的一方还是一的一方,如果relationship定义在一的一方那就是一对多. 
这里的例子中,一指的是Parent,一个parent有多个child:

class Parent(Base):__tablename__ = 'parent'id = Column(Integer,primary_key = True)children = relationship("Child",backref='parent')class Child(Base):__tablename__ = 'child'id = Column(Integer,primary_key = True)parent_id = Column(Integer,ForeignKey('parent.id'))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

多对一(many to one):

这个例子中many是指parent了,意思是一个child可能有多个parent(父亲和母亲),这里的外键(child_id)和relationship(child)都定义在多(parent)的一方:

class Parent(Base):__tablename__ = 'parent'id = Column(Integer, primary_key=True)child_id = Column(Integer, ForeignKey('child.id'))child = relationship("Child", backref="parents")class Child(Base):__tablename__ = 'child'id = Column(Integer, primary_key=True)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

为了建立双向关系,可以在relationship()中设置backref,Child对象就有parents属性.设置 cascade= ‘all’,可以级联删除:

class Parent(Base):__tablename__ = 'parent'id = Column(Integer,primary_key = True)children = relationship("Child",cascade='all',backref='parent')def delete_parent():session = Session()parent = session.query(Parent).get(2)session.delete(parent)session.commit()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

不过不设置cascade,删除parent时,其关联的chilren不会删除,只会把chilren关联的parent.id置为空,设置cascade后就可以级联删除children

一对一(one to one):

一对一就是多对一和一对多的一个特例,只需在relationship加上一个参数uselist=False替换多的一端就是一对一: 
从一对多转换到一对一:

class Parent(Base):__tablename__ = 'parent'id = Column(Integer, primary_key=True)child = relationship("Child", uselist=False, backref="parent")class Child(Base):__tablename__ = 'child'id = Column(Integer, primary_key=True)
parent_id = Column(Integer, ForeignKey('parent.id'))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

从多对一转换到一对一:

class Parent(Base):__tablename__ = 'parent'id = Column(Integer, primary_key=True)child_id = Column(Integer, ForeignKey('child.id'))child = relationship("Child", backref=backref("parent", uselist=False))class Child(Base):__tablename__ = 'child'id = Column(Integer, primary_key=True)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

多对多(many to many):

多对多关系需要一个中间关联表,通过参数secondary来指定,

from sqlalchemy import Table,Text
post_keywords = Table('post_keywords',Base.metadata,Column('post_id',Integer,ForeignKey('posts.id')),Column('keyword_id',Integer,ForeignKey('keywords.id'))
)class BlogPost(Base):__tablename__ = 'posts'id = Column(Integer,primary_key=True)body = Column(Text)keywords = relationship('Keyword',secondary=post_keywords,backref='posts')class Keyword(Base):__tablename__ = 'keywords'id = Column(Integer,primary_key = True)keyword = Column(String(50),nullable=False,unique=True)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

七、关联查询(query with join)

简单地可以使用:

>>> for u, a in session.query(User, Address).\
...                     filter(User.id==Address.user_id).\
...                     filter(Address.email_address=='jack@google.com').\
...                     all():
...     print(u)
...     print(a)
<User(name='jack', fullname='Jack Bean', password='gjffdd')>
<Address(email_address='jack@google.com')>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

如果是使用真正的关联SQL语法来查询可以使用:

>>> session.query(User).join(Address).\
...         filter(Address.email_address=='jack@google.com').\
...         all()
[<User(name='jack', fullname='Jack Bean', password='gjffdd')>]
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

因为这里的外键就一个,系统知道如何去关联

八、常用参数解释:

relationship():函数接收的参数非常多,比如:backref,secondary,primaryjoin,等等。列举一下我用到的参数: 
backref:在一对多或多对一之间建立双向关系,比如:

class Parent(Base):__tablename__ = 'parent'id = Column(Integer, primary_key=True)children = relationship("Child", backref="parent")class Child(Base):__tablename__ = 'child'id = Column(Integer, primary_key=True)parent_id = Column(Integer, ForeignKey('parent.id'))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

Prarent对象获取children,parent.children,反过来Child对象可以获取parent:child.parent.

lazy:默认值是True,说明关联对象只有到真正访问的时候才会去查询数据库,比如有parent对象,只有知道访问parent.children的时候才做关联查询.

remote_side:表中的外键引用的是自身时,如Node类,如果想表示多对一的关系,那么就可以使用remote_side

class Node(Base):__tablename__ = 'node'id = Column(Integer, primary_key=True)parent_id = Column(Integer, ForeignKey('node.id'))data = Column(String(50))parent = relationship("Node", remote_side=[id])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

如果是想建立一种双向的关系,那么还是结合backref:

class Node(Base):
__tablename__ = 'node'
id = Column(Integer, primary_key=True)
parent_id = Column(Integer, ForeignKey('node.id'))
data = Column(String(50))
children = relationship("Node",backref=backref('parent', remote_side=[id]))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

primaryjoin:用在一对多或者多对一的关系中,默认情况连接条件就是主键与另一端的外键,用primaryjoin参数可以用来指定连接条件 ,比如:下面user的address必须现address是一’tony’开头:

class User(Base):__tablename__ = 'user'id = Column(Integer, primary_key=True)name = Column(String)addresses = relationship("Address",primaryjoin="and_(User.id==Address.user_id, ""Address.email.startswith('tony'))",backref="user")class Address(Base):__tablename__ = 'address'id = Column(Integer, primary_key=True)email = Column(String)user_id = Column(Integer, ForeignKey('user.id'))
secondary:
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

order_by: 
在一对多的关系中,如下代码:

class User(Base):
....
addresses = relationship("Address",order_by="desc(Address.email)",primaryjoin="Address.user_id==User.id")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

如果user的address要按照email排序,那么就可以在relationship中添加参数order_by.这里的参数是一字符串形式表示的,不过它等同于python表达式,其实还有另一种基于lambda的方式:

class User(Base):
...
addresses = relationship(lambda: Address,order_by=lambda: desc(Address.email),primaryjoin=lambda: Address.user_id==User.id)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

九、简单的例子

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
from sqlalchemy.orm import mapper, sessionmaker__author__ = 'jpzhang'from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData
from sqlalchemy.sql.expression import Cast
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.dialects.mysql import \BIGINT, BINARY, BIT, BLOB, BOOLEAN, CHAR, DATE, \DATETIME, DECIMAL, DECIMAL, DOUBLE, ENUM, FLOAT, INTEGER, \LONGBLOB, LONGTEXT, MEDIUMBLOB, MEDIUMINT, MEDIUMTEXT, NCHAR, \NUMERIC, NVARCHAR, REAL, SET, SMALLINT, TEXT, TIME, TIMESTAMP, \TINYBLOB, TINYINT, TINYTEXT, VARBINARY, VARCHAR, YEAR#表的属性描述对象
metadata = MetaData()
userTable = Table("wzp_user",metadata,Column('user_id', Integer, primary_key=True),Column('user_name', VARCHAR(50), unique=True, nullable=False),Column('password', VARCHAR(40), nullable=True)
)
#创建数据库连接,MySQLdb连接方式
mysql_db = create_engine('mysql://用户名:密码@ip:port/dbname')
#创建数据库连接,使用 mysql-connector-python连接方式
#mysql_db = create_engine("mysql+mysqlconnector://用户名:密码@ip:port/dbname")
#生成表
metadata.create_all(mysql_db)#创建一个映射类
class User(object):pass
#把表映射到类
mapper(User, userTable)
#创建了一个自定义了的 Session类
Session = sessionmaker()
#将创建的数据库连接关联到这个session
Session.configure(bind=mysql_db)
session = Session()def main():u = User()#给映射类添加以下必要的属性,因为上面创建表指定这个字段不能为空,且唯一u.user_name='tan9le测试'#按照上面创建表的相关代码,这个字段允许为空u.password='123456'#在session中添加内容session.add(u)#保存数据session.flush()#数据库事务的提交,sisson自动过期而不需要关闭session.commit()#query() 简单的理解就是select() 的支持 ORM 的替代方法,可以接受任意组合的 class/column 表达式query = session.query(User)#列出所有userprint list(query)#根据主键显示print query.get(1)#类似于SQL的where,打印其中的第一个print query.filter_by(user_name='tan9le测试').first()u = query.filter_by(user_name='tan9le测试').first()#修改其密码字段u.password = '654321'#提交事务session.commit()#打印会出现新密码print query.get(1).password#根据id字段排序,打印其中的用户名和密码for instance in session.query(User).order_by(User.user_id):print instance.user_name, instance.password#释放资源session.close()if __name__ == '__main__':main()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 8
相关文章推荐

Python SQLAlchemy相关推荐

  1. python sqlalchemy操作SQLite

    日期转时间: from sqlalchemy import Column, Integer, String, Float, Date date = Column(Date) data="20 ...

  2. Python SqlAlchemy使用方法

    1.初始化连接 from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker engine = create ...

  3. Python SQLAlchemy入门教程

    原文:https://www.cnblogs.com/ybjourney/p/11832045.html Python SQLAlchemy入门教程 一.介绍 关于ORM 为什么用sqlalchemy ...

  4. Python SQLAlchemy --3

    本文為 Python SQLAlchemy ORM 一系列教學文: 刪除 學會如何查詢之後,就能夠進行後續的刪除.更新等操作. 同樣地,以幾個範例做為學習的捷徑. 123456789 user_1 = ...

  5. Python sqlalchemy 连接常用的数据库

    python连接sqlServer数据库,Oracle数据库,MongoDB数据库,mysql数据库 python sqlalchemy 简介 学习链接 sqlalchemy是什么? sqlalche ...

  6. Python SQLAlchemy介绍

    Python SQLAlchemy教程 一. 介绍 关于ORM 二. 使用 概念和数据类型 概念 常见数据类型 使用步骤 创建数据库表 1.安装 2. 创建连接 3. 创建数据库表类(模型) 4. 生 ...

  7. Python - SQLAlchemy 子查询

    Python - SQLAlchemy 子查询 Max.Bai 2020-08 1. 子查询需要先执行subquery 2. 子查询的列需要通过c来访问  比如: sub_query.c.alarm ...

  8. python sqlalchemy中文手册-基于Python的SQLAlchemy的操作

    安装 在Python使用SQLAlchemy的首要前提是安装相应的模块,当然作为python的优势,可以到python安装目录下的scripts下,同时按住shift+加上鼠标左键,从而在菜单中打开命 ...

  9. Python SQLAlchemy

    SQLAlchemy介绍 SQLAlchemy是一个基于Python的ORM框架.该框架是建立在DB-API之上,使用关系对象映射进行数据库操作. 简而言之就是,将类和对象转换成SQL,然后使用数据A ...

最新文章

  1. wdcp导出mysql_phpmyadmin导入导出mysql(只适用WDCP系统)
  2. python中高阶函数改写学生信息管理程序_python利用高阶函数实现剪枝函数
  3. 约瑟夫环算法c语言,约瑟夫环的c语言实现(代码已实现)
  4. Vuex的全面用法总结
  5. 深入浅出Mybatis系列(一)---Mybatis入门[转]
  6. webcrypto库下载_使用WebCrypto API的电子签名
  7. 谷歌招聘主管公开八大求职秘诀
  8. 1.3编程基础之算术表达式与顺序执行 09 与圆相关的计算
  9. vscode找不到config_vscode中的 jsconfig.json
  10. Eclipse 调试器
  11. PyQt5 GUI Programming With Python 3.6 (一)
  12. Windows7系统运行hadoop报Failed to locate the winutils binary in the hadoop binary path错误
  13. setState如何知道该做什么?
  14. 给对象添加属性和给对象原型添加属性的区别
  15. 拓端tecdat|R语言多维数据层次聚类散点图矩阵、配对图、平行坐标图、树状图可视化城市宏观经济指标数据
  16. linux修改时区不用重启服务,Linux修改时区不用重启的方法
  17. python安装包错误的问题
  18. 傻妞机器人老版安装教程
  19. linux串口结构termios,struct termios结构体—Linux串口.doc
  20. 凯恩斯乘数到底有多么神奇?

热门文章

  1. 讲座笔记 | 刘守英 教授讲座 王永钦 教授讲座
  2. 蓝牙通信,通过蓝牙传照片
  3. php给照片加滤镜,加滤镜、消痘痘!Win 10系统自带的“照片”你用过吗?
  4. 产品,开发,业务的科学吵架指南:每次吵完架后都觉得自己没发挥好怎么办?...
  5. Nature | 微小的降雨变化极大地改变了植物的物种共存
  6. fastdfs-client使用
  7. @程序员,终于可以放心写bug了!Facebook的debug神器你值得拥有
  8. 2021 物流门店消防解决方案
  9. Modbus Tcp通信格式详解
  10. 通过扩展 Rational Functional Tester 对 Adobe Flex 或 Flash 应用程序进行测试