web项目运行时无法重命名MySQL表问题排查

12 篇文章 0 订阅

问题描述:web应用在线上运行,使用SQLAlchemy,没有用户在进行增删改查,甚至没有用户登陆,但在后台无法对相应MySQL表进行重命名或删除,显示锁定,但可以增删改查。

本以为是锁或连接池的问题,其实跟锁或连接池没关系,实际上是对SQLAlchemy连接使用不当造成的,主要是使用完没有进行session.close(),本来使用with上下文管理器,参考SQlALchemy session详解

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
Base = declarative_base()
class Users(Base):
    __tablename__ = 'users'
    user_id = Column(Integer, primary_key=True, comment='自增ID')
    user_name = Column(String, comment='用户名')

from sqlalchemy.orm import sessionmaker
DbSession = sessionmaker(bind=engine)  # 创建session

from contextlib import contextmanager
@contextmanager
def session_maker(session=DbSession):  # 封装上下文方法
    try:
        yield session()
        session.commit()
    except:
        session.rollback()
        raise
    finally:
        session.close()

# 调用:
def my_user():
    with session_maker() as db_session:
        user = db_session.query(Users).filter_by(name='Dale').one_or_none()

本质上约等于try... finally... 按照上边的调用其实没问题,但我把with session_maker(session=session) as db: self.db = db 放到了类的__init__里了:

class MyClass():
    def __init__(self):
        with session_maker(DbSession) as db:
            self.db = db
    
    def myfunc():
        self.db.query(Users).filter_by(name='Dale').one_or_none()

然后在方法中使用时直接用self.db,这样在方法使用完时是没有进行session.close()的,而打开数据库表本质上是打开文件的操作,session.close本质上是关闭打开的文件,解除系统资源占用。如此导致可以增删改查相关表,但无法重命名和删除之类的操作。

但在类中,更pythonic的做法是使用__del__,自动销毁对象:

class MyClass():
    def __init__(self):
        with session_maker(DbSession) as db:
            self.db = db  # 使用其中的自动commit()
    
    # def __init__(self):  # 正常
    #     self.db = DbSession()
    
    def __del__(self):
        self.db.close()  # 必要
    
    def myfunc():
        self.db.query(Users).filter_by(name='Dale').one_or_none()
 

这样就可以重命名表操作了。

参考资料:

https://zhuanlan.zhihu.com/p/92233555

https://www.jianshu.com/p/5b01fb36fd4c

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值