使用SQLAlchemy报错AttributeError: 'sessionmaker' object has no attribute 'add'

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__这个东东?

精简代码,方便接口调用的“约定俗成”
其他原因暂时不太理解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值