使用SQLAlchemy和检索所有列在Flask中的多个非外键列上连接2个表

时间:2013-04-11 23:20:12

标签: sqlalchemy flask flask-sqlalchemy

我有一些表格如下所示,我想加入不是彼此表的外键的列,然后可以访问两者的列。以下是课程:

class Yi(db.Model):

    year = db.Column(db.Integer(4), primary_key=True)
    industry_id = db.Column(db.String(5), primary_key=True)
    wage = db.Column(db.Float())
    complexity = db.Column(db.Float())

class Ygi(db.Model, AutoSerialize):

    year = db.Column(db.Integer(4), primary_key=True)
    geo_id = db.Column(db.String(8), primary_key=True)
    industry_id = db.Column(db.String(5), primary_key=True)
    wage = db.Column(db.Float())

所以,我想得到的是两个表的列,这些列由我指定的ID连接,在本例中为Year和industry_id。这可能吗?这是我为实现这个目的编写的SQL ...

SELECT 
    yi.complexity, ygi.* 
FROM
    yi, ygi 
WHERE 
    yi.year = ygi.year and 
    yi.industry_id = ygi.industry_id

1 个答案:

答案 0 :(得分:1)

一种肮脏的方式是:

q=session.query(Ygi,Yi.complexity).\
          filter(Yi.year==Ygi.year).\
          filter(Yi.industry_id==Ygi.industry_id)

这给了你:

SELECT ygi.year AS ygi_year, ygi.geo_id AS ygi_geo_id, 
       ygi.industry_id AS ygi_industry_id, ygi.wage AS ygi_wage,
       yi.complexity AS yi_complexity 
FROM ygi, yi 
WHERE yi.year = ygi.year 
AND yi.industry_id = ygi.industry_id

我发现这个因为它没有使用 join()方法。 您可以了解如何将 join()the SQLAlchemy documentation

一起使用

然后,您可以选择使用虚拟模型:请参阅此问题Mapping a 'fake' object in SQLAlchemy TokenMacGuy 的答案。 这将是一个很好的解决方案。

或者你只有一个 YiYgi类,它不是sqlalchemy.Base派生类,而只是一个对象。它更像是一种“手工时尚”的方式。

该类将有一个classmethod get()方法:

  1. 调用您之前构建的查询,
  2. 使用返回的请求行调用 init 并为每行构建一个实例
  3. 这是一个例子:

    class YiYgi(object):
    
        def __init__(self,year, geo_id, industry_id, wage, complexity):
            # Initialize all your fields
            self.year = year
            self.geo_id = geo_id
            self.industry_id = industry_id
            self.wage = wage + 100  # You can even make some modifications to the values     here
            self.complexity = complexity
    
        @classmethod
        def get_by_year_and_industry(cls, year, industry_id):
            """ Return a list of YiYgi instances, void list if nothing available """
            q = session.query(Ygi,Yi.complexity).\
                        filter(Yi.year==Ygi.year).\
                        filter(Yi.industry_id==Ygi.industry_id)
    
            results = q.all()
    
            yiygi_list = []
            for result in results:
                # result is a tuple with (YGi instance, Yi.complexity value)
                ygi_result = result[0]
                yiygi = YiYgi(ygi_result.ygi_year, 
                              ygi_result.geo_id,
                              ygi_result.industry_id,
                              ygi_result.wage,
                              result[1])
    
                yiygi_list.append(yiygi)
    
            return yiygi_list