查询sqlalchemy模型的外键

querying the foreign key of a sqlalchemy model

一段时间以来,我一直在尝试弄清楚如何 运行 基于 SQLAlchemy 模型的外键进行查询,我已经尝试检查文档并在 Whosebug 上查看此处,但我做不到找到解决我遇到的这个问题的任何东西。我有 2 个 SQLAlchemy 模型:用户和帐户定义如下:

class User(db.Model):
  __tablename__ = 'user'

  id = db.Column(db.Integer, primary_key=True)
  fName = db.Column(db.String(255))
  accounts = db.relationship("Account")

class Account(db.Model):
  __tablename__ = 'account'

  id = db.Column(db.Integer, primary_key=True)
  account_number = db.Column(db.Integer, unique=True, nullable=False)
  lName = db.Column(db.String(255), nullable=False)
  client_id = db.Column(db.ForeignKey("user.id"))

我想做的是查询帐户模型中的所有帐户,如果它在 client_id 外键引用的用户模型列中有相应的值,则为每个帐户添加最终结果中来自用户模型的 fName 的值。所以它看起来像这样:

{
  "accounts": [
    {
      "fName": "Abbie",
      "id": 1,
      "account_number": 1234,
      "lName": "Mills"
    },
    {
      "fName": "Katrina",
      "id": 2,
      "account_number": 3848,
      "lName": "Crane"
    },
    {
      "fName": "Sheldon",
      "id": 3,
      "account_number": 384,
      "lName": "Cooper"
    },
    {
      "fName": "Chandler",
      "id": 4,
      "account_number": 1288,
      "lName": "Bing"
    },
    {
      "id": 5,
      "account_number": 1283,
      "lName": "Smith"
    },
    {
      "id": 6,
      "account_number": 3847,
      "lName": "Gary"
    },
    {
      "id": 7,
      "account_number": 2038,
      "lName": "Ryan"
    }
  ]
}

我知道这是我想要的查询:

class AccountList(Resource):
    @account_ns.doc('get account data')
    def get(self):
        query = account_schema.dump(Account.query.all())
        accountDict = {}
        accountDict['accounts'] = []
        for item in query:
            itemDict = {}
            itemDict = item
            linkQuery = user_schema.dump(db.session.query(User.fName).filter(User.id == Account.client_id).first())
            # print(linkQuery)
            itemDict.update(linkQuery)
            accountDict['accounts'].append(itemDict)
        print(accountDict)
     return accountDict, 200

但每次查询 db.session.query(User.fName).filter(User.id == Account.client_id).first() 都是 运行,id of User 似乎并没有递增,并且每次都打印相同的值,即使对于没有 client_id 的帐户对象也是如此。结果是这样的:

{
  "accounts": [
    {
      "customer_id": 1,
      "id": 1,
      "lName": "Mills",
      "account_number": 1234,
      "fName": "Abbie"
    },
    {
      "customer_id": null,
      "id": 2,
      "lName": "Smith",
      "account_number": 1283,
      "fName": "Abbie"
    },
    {
      "customer_id": null,
      "id": 3,
      "lName": "Gary",
      "account_number": 484,
      "fName": "Abbie"
    },
    {
      "customer_id": 2,
      "id": 4,
      "lName": "Crane",
      "account_number": 3848,
      "fName": "Abbie"
    },
    {
      "customer_id": 3,
      "id": 5,
      "lName": "Cooper",
      "account_number": 384,
      "fName": "Abbie"
    },
    {
      "customer_id": null,
      "id": 6,
      "lName": "Ryan",
      "account_number": 223,
      "fName": "Abbie"
    },
    {
      "customer_id": 1,
      "id": 7,
      "lName": "Mills",
      "account_number": 48494,
      "fName": "Abbie"
    },
    {
      "customer_id": 4,
      "id": 9,
      "lName": "Bing",
      "account_number": 1288,
      "fName": "Abbie"
    }
  ]
}

这不是我想要的。我在这里做错了什么或者我可以以某种方式调整我的查询吗?我想到的唯一其他方法是在帐户中创建另一个列,该列具有与 client_id 相同的值但未设置为外键,以便我实际上可以引用该列中行的值。

我已经坚持了一段时间,所以非常感谢任何帮助。谢谢!

Sqlalchemy 支持模型中的反向引用。在应用关系时,您还可以使用 pass backref 参数,这将帮助您直接从帐户对象访问用户对象。

class User(db.Model):
  __tablename__ = 'user'

  id = db.Column(db.Integer, primary_key=True)
  fName = db.Column(db.String(255))
  accounts = db.relationship("Account", backref="user")

class Account(db.Model):
  __tablename__ = 'account'

  id = db.Column(db.Integer, primary_key=True)
  account_number = db.Column(db.Integer, unique=True, nullable=False)
  lName = db.Column(db.String(255), nullable=False)
  client_id = db.Column(db.ForeignKey("user.id"))

class AccountList(Resource):
    @account_ns.doc('get account data')
    def get(self):
        query = Account.query.all()
        account_list = []
        for item in query:
            account_dict = item.__dict__
            if item.client_id:
                accout_dict["fName"] = item.user.fName
            account_list.append(account_dict)
     return account_list, 200