gpt4 book ai didi

python - SqlAlchemy:自引用默认值作为查询

转载 作者:太空狗 更新时间:2023-10-30 02:46:35 24 4
gpt4 key购买 nike

假设我有以下结构(使用 Flask-SqlAlchemy):

class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, nullable=False, index=True)
# The following line throws an error at runtime.
variant = db.Column(db.Integer, nullable=False, index=True,
default=select(func.count(User.id)).where(User.name == self.name))

def __init__(self, name):
super(User, self).__init__()
self.name = name

@property
def clause(self):
return '/'.join([str(self.variant), self.name])

问题是,“用户未定义。”我想为一个系统建模,用户可以选择相同的名称,但添加一个字段以系统方式区分用户,而不使用(从而公开)“id”字段。

有人知道如何进行自引用查询来填充默认值吗?

最佳答案

此处默认未指代用户的问题通过在用户可用后将“默认”分配给列来解决。但是,这并不能解决这里的问题,因为“self”也没有任何意义,没有调用 User 方法,所以你不能只引用“self”。此语句的挑战在于您希望它呈现为内联子 SELECT,但它仍然需要知道“.name”的内存值。因此,您必须以某种方式为每个对象分配子 SELECT。

人们处理 ORM 级 INSERT 默认值的通常方式通常是使用 before_insert处理程序。

另一种值得指出的方法是创建 SQL 级别的 INSERT 触发器。这是总体上最“传统”的方法,因为在这里您需要访问要插入的行;触发器定义了一种获取正在插入的行值的方法。

至于在列级别使用默认值,您需要使用可调用函数作为默认值,它可以查看正在插入的行的当前值,但目前这意味着您的 SELECT 语句将不与 INSERT 语句内联呈现,您需要预先执行 SELECT,这并不是我们真正想要的。

无论如何,将 SQL 表达式呈现到 INSERT 中,同时让该 SQL 表达式引用某些本地的每个对象状态的基本任务是通过将该表达式分配给属性来实现的,ORM 在刷新时选择了这一点。下面我们在构造函数中执行此操作,但这也可以发生在 before_insert() 内部:

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
name = Column(String, nullable=False, index=True)
variant = Column(Integer, nullable=False, index=True)

def __init__(self, name):
self.name = name
self.variant = select([func.count(User.id)]).where(User.name == self.name)

e = create_engine("sqlite://", echo=True)

Base.metadata.create_all(e)

s = Session(e)

s.add(User(name='n1'))
s.commit()

s.add(User(name='n1'))
s.commit()

print s.query(User.variant).all()

关于python - SqlAlchemy:自引用默认值作为查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19609883/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com