【问题标题】:nonSQL related attribute add to SQLAlchemy model error非 SQL 相关属性添加到 SQLAlchemy 模型错误
【发布时间】:2017-02-07 23:33:44
【问题描述】:

我正在使用 python 和烧瓶开发一个网络应用程序。我使用 Flask、SQLAlchemy 和 PostgreSQL 进行开发。我有多对一相关模型。通过这种模型,一家公司可以拥有多个用户,但每个用户只能拥有一家公司。

models.py
class Company(ResourceMixin, db.Model):
    __tablename__ = 'companies'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), unique=True, index=True, 
                     nullable=False, server_default='')
    phone = db.Column(db.String(24)) 
    email = db.Column(db.String(255), index=True)
    address = db.Column(db.String(255))

    # Relations
    users = db.relationship('User', backref='company')

class User(UserMixin, ResourceMixin, db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)

    # User details
    name = db.Column(db.String(50), index=True)
    phone = db.Column(db.String(24)) 
    address = db.Column(db.String(255))
    email = db.Column(db.String(255), unique=True, index=True, nullable=False,
                      server_default='')
    password = db.Column(db.String(128), nullable=False, server_default='')

    # Relations
    company_id = db.Column(db.Integer, db.ForeignKey('companies.id', 
                                                     onupdate='CASCADE',
                                                     ondelete='SET NULL'), 
                           index=True)


views.py
app.route('/')
def index():
    company = Company.query.get(1)
    flash(company.name, company.user_count)
    return render_template('index.html')

错误摘要:“user_count”属性不是公司模型的一部分。

我想从公司模型中动态获取用户数。属性应在模型的每次调用中计算用户数,并在常规属性上提供服务(如 company.user_count)。我通过创建一个类方法并在视图函数中调用它来实现它,但我希望它使过程自动化,而无需在使用属性之前调用方法。

我尝试了这样的 init 函数:

def __init__(self):
    self.user_count = len(self.users)

像这样:

def __init__(self):
    self.status()

def status(self):
    self.user_count = len(self.users)
    return True

像这样:

def __init__(self):
    self.status()

@classmethod
def status(self):
    self.user_count = len(self.users)
    return True

所有三个版本都会引发相同的错误。我该如何克服这个问题。

非常感谢!

【问题讨论】:

    标签: python postgresql class flask sqlalchemy


    【解决方案1】:

    你可以使用一个属性:

    class User(Base):
        ...
        @property
        def user_count(self):
            return len(self.users)
    

    【讨论】:

    • 嗨!我尝试了@property,它就像魅力一样。我如何直接调用属性。但是仍然存在一个问题。我想在 order_by 方法中使用它。我使用order_by(cast(Company.user_count, Integer)),但它会抛出AttributeError: 'int' object has no attribute 'get_children' 错误。如果我尝试与Company.id 相同的代码,它可以工作。因此,新财产在某种程度上与其他财产不同。 (注:我也试过@hybrid_property,结果是一样的)
    • @CarnageTR 当然不一样;它不是 SQL 中的真正列!如果您需要通过user_count 订购,您有三种选择(按性能排序): 1. 使用子查询,即ORDER BY (SELECT count(*) FROM users WHERE users.company_id = companies.id); 2. 使用连接和聚合,例如SELECT * FROM (SELECT *, count(*) AS cnt FROM companies JOIN users ON users.company_id = companies.id GROUP BY companies.id) subq ORDER BY subq.cnt; 3. 对user_count 列进行非规范化,并在每次添加或删除用户时更新计数。
    猜你喜欢
    • 2018-08-22
    • 2020-03-16
    • 1970-01-01
    • 2018-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多