如何在不使用ORM对象的情况下用SQLAlchemy更新数据库表条目?
解决SQLAlchemy处理超大量列数据表的增删改问题
你遇到的核心问题是:通过Table对象查询返回的是只读的Row对象,无法直接像ORM模型实例那样修改属性。下面提供两种实用方案,覆盖增、删、改全操作:
方案一:直接使用SQLAlchemy Core执行操作
无需创建ORM类,直接通过Core的update/insert/delete语句操作,适合快速处理单条或批量数据:
更新操作
如果已知要修改的条件和字段,直接构造更新语句:
from datetime import date import sqlalchemy as sa import sqlalchemy.orm as orm engine = sa.create_engine('sqlite:///FullDatabase.db') meta = sa.MetaData(engine) history = sa.Table('history', meta, autoload=True) session = orm.Session(engine) # 直接按条件更新指定字段 session.execute( sa.update(history) .where(history.c.Date == date(2023, 1, 25)) .values(HousePrice=100) ) session.commit()
如果需要先读取数据再修改,可以把Row对象转成字典后更新:
entry = session.query(history).where(history.c.Date == date(2023, 1, 25)).first() # 将Row转为可修改的字典 entry_dict = dict(entry._mapping) entry_dict['HousePrice'] = 100 session.execute( sa.update(history) .where(history.c.Date == date(2023, 1, 25)) .values(**entry_dict) ) session.commit()
新增操作
构造字典传入insert语句:
new_data = { 'Date': date(2023, 1, 26), 'HousePrice': 200, # 其他字段按需填充,不需要手动写全1000+列,缺省的会用数据库默认值 } session.execute(sa.insert(history).values(**new_data)) session.commit()
删除操作
按条件执行删除:
session.execute( sa.delete(history) .where(history.c.Date == date(2023, 1, 25)) ) session.commit()
方案二:动态生成ORM类(推荐)
通过动态创建ORM类,实现和普通declarative模型完全一致的操作体验,适合需要频繁操作该表的场景:
from datetime import date import sqlalchemy as sa import sqlalchemy.orm as orm from sqlalchemy.ext.declarative import declarative_base engine = sa.create_engine('sqlite:///FullDatabase.db') meta = sa.MetaData(engine) history = sa.Table('history', meta, autoload=True) # 动态生成ORM类,绑定已加载的Table对象 Base = declarative_base() History = type('History', (Base,), {'__table__': history}) session = orm.Session(engine) # 更新操作:和普通ORM模型完全一样 entry = session.query(History).where(History.Date == date(2023, 1, 25)).first() entry.HousePrice = 100 session.commit() # 新增操作 new_entry = History(Date=date(2023, 1, 26), HousePrice=200) session.add(new_entry) session.commit() # 删除操作 entry = session.query(History).where(History.Date == date(2023, 1, 25)).first() session.delete(entry) session.commit()
为什么动态生成可行?
SQLAlchemy的declarative模型本质就是继承Base并绑定__table__属性的类。我们通过type()动态创建类,直接把自动加载的history表绑定到__table__,就得到了功能完整的ORM模型,无需手动定义1000+列。
内容的提问来源于stack exchange,提问作者Gcedism
相关产品推荐
相关产品推荐

