SQLAlchemy如何创建表并增加一条记录
初学ORM工具之SQLAlchemy操作MySQL,结果混淆了sessionmaker和它的实例。
sessionmaker需要先绑定engine,然后实例化一个session,这个session才可以用于CURD。
正确的代码:
# SQLAlchemy如何创建表并增加一条记录
from sqlalchemy import create_engine # sqlalchemy的引擎
from sqlalchemy.ext.declarative import declarative_base # 用于创建数据库中表的基类
from sqlalchemy import String,Column,Integer # 字段类,整形和字符串类
from sqlalchemy.orm import sessionmaker # 预配置范围的会话(session),代替connect执行数据库操作
Base = declarative_base()
class Student(Base): #必须继承declaraive_base得到的基类
__tablename__ = "Students" #用__tablename__来指定这个类对应什么表,如果这个表在库中不存在,SQLAlchemy会帮我们创建
Sno = Column(String(10),primary_key=True) #Column类创建一个字段
Sname = Column(String(20),nullable=False,unique=True,index=True)
Ssex = Column(String(2),nullable=False)
Sage = Column(Integer,nullable=False)
Sdept = Column(String(20))
if __name__=='__main__':
engine = create_engine("mysql+pymysql://root:root@127.0.0.1:3306/test")
Session = sessionmaker(bind=engine) # 实例化 sessionmaker,绑定engine
sess = Session() #实例化了一个会话(或叫事务),之后的所有操作都是基于这个对象的
stu = Student(Sno='9',Sname='zha',Ssex='M',Sage=23)
sess.add(stu) # 增加一条记录
sess.commit() # 一定记得提交
sess.close()
对于sessionmaker实例化之后又调用了一次,我非常不能理解,去GitHub看了一下源代码,大概长这样子
class sessionmaker(_SessionClassMethods):
def __init__(
self,
bind=None,
class_=Session,
autoflush=True,
autocommit=False,
expire_on_commit=True,
info=None,
**kw
):
kw["bind"] = bind
kw["autoflush"] = autoflush
kw["autocommit"] = autocommit
kw["expire_on_commit"] = expire_on_commit
if info is not None:
kw["info"] = info
self.kw = kw
self.class_ = type(class_.__name__, (class_,), {})
def __call__(self, **local_kw):
for k, v in self.kw.items():
if k == "info" and "info" in local_kw:
d = v.copy()
d.update(local_kw["info"])
local_kw["info"] = d
else:
local_kw.setdefault(k, v)
return self.class_(**local_kw)
......
在Python的类中__init__函数是用来初始化的,__call__呢?
关于 call 方法,不得不先提到一个概念,就是可调用对象(callable),我们平时自定义的函数、内置函数和类都属于可调用对象,但凡是可以把一对括号()应用到某个对象身上都可称之为可调用对象,判断对象是否为可调用对象可以用函数 callable。
如果在类中实现了__call__方法,那么这个类的实例对象也将是一个可调用对象。如果没有实现__call__方法,调用的时候会报错 TypeError: ‘person’ object is not callable。
class person:
def __init__(self,name=None):
self.name = name
print('object initing...')
def __call__(self):
print('object calling...')
person1 = person('zhang')
person1()
用普通的函数也可实现,为什么要引入__call__这个东东?
精简代码,方便接口调用的“约定俗成”
其他原因暂时不太理解