这是我发布的关于使用 SQLALCHEMY 创建动态表和列的帖子的后续内容。 SQLAlchemy 创建动态表和列
大多数展示如何在 Python 和 SQLAlchemy 中创建动态表和列的教程都侧重于创建类对象 - 使用
Declarative
,这样每次使用类都会创建一个包含预定义列和定义的列元数据的表在那个班级(见下文)。这种创建表的方式的问题是,至少据我所知,它不允许我动态创建列。我正在阅读 API 并获取每天都会更改的表的元数据,因此我需要一种动态创建这些表的方法 - 请参阅我的原始帖子:SQLAlchemy 创建动态表和列
例如,据我了解,以下构造不允许为表创建动态列,例如我原来的帖子:
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)
fullname = Column(String)
password = Column(String)
我在这方面询问类对象的原因是因为展示如何查询数据库的教程需要在查询中使用类对象。 例如,我研究过的每种查询数据库以查找每个表中最新值的方法(假设它是主键或最大
id
的最大值timestamp
)似乎都需要使用当前的类对象我不做。
Session = sessionmaker(bind=engine)
session = Session()
User.query.order_by('timestamp desc').limit(1)
是否可以构建一个将创建动态列的类对象?使用类对象?
如果没有,是否有另一种最佳实践使用 SQLAlchemy 查询数据库以查找表中的最新记录?
请参阅有关 SQLAlchemy 的这篇博客文章 - 很棒的教程,我已经读过。
我研究过的每一种查询数据库以查找每个表中最新值的方法......似乎都需要使用类对象
这是一个误解:虽然教程倾向于关注 ORM 层,但核心层提供了查询数据库所需的所有工具。例如,而不是
with Session() as s:
q = sa.select(User).order_by(User.timestamp.desc()).limit(1)
latest_user = s.scalar(q)
做
with engine.connect() as conn:
q = sa.select(users).order_by(users.c.timestamp.desc()).limit(1)
latest_user = conn.execute(q).fetchone()
如果需要 ORM 层功能 - 通常是为了处理依赖对象的图 - 还有声明式的替代方案:
import sqlalchemy as sa
from sqlalchemy import orm
engine = sa.create_engine('postgresql+psycopg2:///so', echo=True)
metadata = sa.MetaData()
# Reflect the required table(s), if not already in the metadata.
metadata.reflect(engine, only=['users'])
users = metadata.tables['users']
# Dynamically create a class.
User = type('User', (), {})
registry = orm.registry(metadata=metadata)
# Map the class to the table (this makes the class a SQLAlchemy ORM entity)
registry.map_imperatively(User, users)
请注意,这些方法都不支持在创建表后添加或删除表中的列。