SQLAlchemy中Base.metadata.drop_all()无法删除表的问题求助
问题分析与解决
嘿,刚看完你的代码,马上就发现了核心问题——你在定义表结构之前就调用了Base.metadata.drop_all()!
为什么旧表删不掉?
Base.metadata.drop_all(bind=engine)的作用是删除所有已经注册到Base.metadata里的表。但你现在的代码顺序是:先执行drop_all,再定义TradeHistory表,这时候Base.metadata里还没有这张表的元数据信息,SQLAlchemy根本不知道要删哪张表,旧的TradeHistory自然就保留下来了。之后调用create_all()时,因为表已经存在,就不会重新创建,新数据自然就追加到旧表里了。
修正步骤 + 优化后的代码
我帮你调整了代码顺序,还修复了几个小细节(比如缺失的导入、混用session和conn的问题):
from sqlalchemy import create_engine, Table, Column, Integer, String from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker # 1. 初始化引擎和会话 engine = create_engine("mysql+pymysql://root:pswd@127.0.0.1:3306/bond?charset=utf8", echo=True) Session = sessionmaker(bind=engine) session = Session() Base = declarative_base(bind=engine) # 2. 先定义表结构,把表注册到Base.metadata中 table = Table('TradeHistory', Base.metadata, Column('Id', Integer, primary_key=True), Column('trade_date', String(50)), Column('rem_period', String(50)), Column('bond_code', String(50)), Column('bond_name', String(50)), Column('bond_rating', String(50)), Column('bond_yield', String(50)), Column('note', String(50)), Column('offer', String(50)), Column('bid', String(50)), Column('amount', String(50))) # 3. 现在执行drop_all,就能找到要删除的TradeHistory表了 Base.metadata.drop_all(bind=engine) # 4. 重新创建表 Base.metadata.create_all(bind=engine) # 5. 用session来插入数据(更符合ORM的用法,避免混用conn和session) session.execute(table.insert(), listToWrite) session.commit() session.close()
额外提醒
- 确保
listToWrite是符合要求的字典列表,比如[{"trade_date": "2024-05-20", ...}, ...] - 如果之后用SQLAlchemy的ORM模型(比如继承Base的类),也要遵循“先定义模型,再执行drop_all/create_all”的顺序
内容的提问来源于stack exchange,提问作者lucyf
相关产品推荐
相关产品推荐

