from sqlalchemy import create_engine
engine = create_engine('sqlite:///:memory:', echo=True)
create_engine返回Engine实例,并没有真正连接数据库,在第一次操作数据库时才真正进行连接
在使用ORM时,需要先描述数据库表进行结构化过程,然后我们定义自己的类来和数据表进行映射。在sqlalchemy中,可以使用Declarative系统进行数据表的创建和相应类的映射。
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
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 "" % (self.name, self.fullname, self.password)
使用Declarative的类至少需要一个__tablename__属性和一个Column表的列来作为主键
在sqlite和postgresql数据库上,在建立表时可以不用指定VARCHAR长度,所以上面写法正确,但是在其它数据库中需要指定长度
name = Column(String(20))
使用Base.metadata.create_all(engine)来创建所有表
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)
session = Session()
或者
from sqlalchemy.orm import sessionmaker
Session = sessionmaker()
Session.configure(bind=engine)
session = Session()
在执行session=Session()获取一个连接对象时,并没有真正打开一个连接,在第一次使用时,从Engine保持的连接池里得到一个连接,并且一直保持到我们提交了所有的提交或者关闭了连接对象
ed_user = User(name="hawk", fullname="hawkyang", password="mypassword")
session.add(ed_user)
our_user = session.query(User).filter_by(name='ed').first()
ed_user is our_user #True
在添加到session的时刻,这个数据实例对象处于pending状态,并没有SQL执行,在数据库中也不会有相应的记录存在。当我们进行查询的时候,所有pending状态的信息都会被flush掉,之后查询会被立即执行。
但是此时数据库中还没有真正写入,需要session.commit()才行
并且,在同一个session中出现的有独特主键的对象,不管查询多少次,得到的都是同一个python对象。
session可以同时添加多条数据
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')])
然后修改已有数据
ed_user.password = 'f8s7ccs'
session.dirty #查看被改变的数据
session.new #查看pending状态的新数据
session.commit() #执行flush操作
在创建ed_user时,并没有id属性,在提交之后,ed_user有了id属性。
不管在session中如何更改数据,最终需要调用commit来真正提交到数据库才能进行持久化
session的一系列操作在一个事务中