【问题标题】:Column-name mapping in SQLAlchemySQLAlchemy 中的列名映射
【发布时间】:2016-09-24 03:40:22
【问题描述】:

我刚刚学习 SQLAlchemy 两天,并且有一个关于列名映射的问题。首先,官方文档中的以下声明让我失去了平衡:

名称上的匹配列适用于简单的情况,但可以变成 处理包含重复的复杂语句时很笨重 列名或使用不容易的匿名 ORM 构造时 匹配特定的名称。此外,还有打字行为 出现在我们的映射列中,我们可能会在 处理结果行。

呃,什么?!这一段试图说的一两个例子会很好,但没关系;这是另一天的任务。

我有点理解,有时我们的查询生成的字段列表不会与模型完美映射,因此我们可以在位置上指定预期的列。这让我试图想出一个这个映射可能有用的例子。所以我想,从动态计算的表中选择一列怎么样?我使用random() 函数在sqlite 数据库中模拟了这一点,如下所示:

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import sessionmaker

engine = create_engine('sqlite:///:memory:', echo=True)
Base = declarative_base()

Session = sessionmaker(bind=engine)
session = Session()

class User(Base):
    __tablename__ = 'users'
    id       = Column(Integer, primary_key=True)
    name     = Column(String)
    fullname = Column(String)
    password = Column(String)

    def __repr__(self):
        return "User<name={}, fullname={}, password={}>".format(self.name, self.fullname, self.password)

# Create all tables
Base.metadata.create_all(engine)

ed_user = User(name='ed', fullname='Ed Jones', password='edspassword')
session.add(ed_user)
session.add_all([
    User(name='wendy', fullname='Wendy Williams', password='foobar'),
    User(name='mary', fullname='Mary Contrary', password='xxg527'),
    User(name='fred', fullname='Fred Flinstone', password='blah')
])
session.commit()

stmt = text("SELECT name, id, fullname, random() FROM users WHERE name=:name")
stmt = stmt.columns(User.name, User.id, User.fullname ...

现在呢?我不能写列名,因为不存在,也不能将它添加到模型定义中,因为该列将被不必要地创建。我只想从数据库中获取一些额外的信息(如NOW()),以便在代码中使用。

如何做到这一点?

【问题讨论】:

    标签: python-3.x sqlalchemy


    【解决方案1】:

    您可以使用column labels

    from sqlalchemy import func
    
    users = session.query(User.id, User.name, User.fullname, func.random().label('random_value'))
    for user in users:
        print(user.id, user.name, user.fullname, user.random_value)
    

    【讨论】:

    • 谢谢!我开始认为没有人会来拯救我(我自己找到了一个有限的解决方案),但这正是我所寻找的。​​span>
    • 有没有办法自动将user 转换为字典?
    【解决方案2】:

    尝试明确列出column 对象。这样“random()”可以是任意的 SQL 计算列...

    # You may have already imported column, but for completeness:
    from sqlalchemy import column
    
    # As an example:
    find_name = 'wendy'
    
    stmt = text("SELECT name, id, fullname, (random()) as random_value FROM users WHERE name=:name")
    stmt = stmt.columns(column('name'), column('id'), column('fullname'), column('random_value'))
    
    users = session.query(column('name'), column('id'), column('fullname'), column('random_value')).from_statement(stmt).params(name = find_name)
    for user in users:
        print(user.id, user.name, user.fullname, user.random_value)
    

    【讨论】:

      【解决方案3】:

      好吧,所以我自己似乎已经解决了这个问题(该死,这是一天两次!这里的 SQLAlchemy 社区似乎已经死了,这迫使我自己寻找答案......虽然不是一件很坏的事情!)。我是这样做的:

      from sqlalchemy import func
      session.query(User.name, User.id, User.fullname, func.current_timestamp()).filter(User.name=='ed').all()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-01
        相关资源
        最近更新 更多