在SQLAlchemy中映射"假"对象

Jam*_*mes 2 python mapping orm sqlalchemy

我不确定这是什么叫,因为它对我来说是新的,但这是我想要做的:

我的数据库中有两个表:TableA和TableB.TableA有pk a_id和另一个叫a_code的字段.TableB有pk b_id和另一个叫做b_code的字段.

我将这些表映射到我的sqlalchemy代码中,它们工作正常.我想创建一个名为TableC的第三个对象,它实际上并不存在于我的数据库中,但它包含a_code和b_code的组合,如下所示:

class TableC:
  a_code = String
  b_code = String
Run Code Online (Sandbox Code Playgroud)

然后我想查询TableC,如:

TableC.query.filter(and_(
        TableC.a_code == x,
        TableC.b_code == y)).all()
Run Code Online (Sandbox Code Playgroud)

问题1)这种类型的东西有名字吗?2)我如何进行映射(使用声明会很好)?

Sin*_*ion 7

我真的不有一个完整的了解查询您所要表达的,天气是一个联盟或加入或一些第三件事,而是放在一边,它肯定可能的映像,从任意选择(什么,你可以把信息传给返回行的数据库).

我将首先假设您需要某种TableA和TableB的并集,这将是A中的所有行,以及B中的所有行.如果您愿意,可以很容易地将其更改为不同的概念.显示有关您正在表达的数据形状的更多信息.

我们将首先在声明式样式中设置真实的表和类来映射它们.

from sqlalchemy import *
import sqlalchemy.ext.declarative

Base = sqlalchemy.ext.declarative.declarative_base()

class TableA(Base):
    __tablename__ = 'a'
    id = Column(Integer, primary_key=True)
    a_code = Column(String)

class TableB(Base):
    __tablename__ = 'b'
    id = Column(Integer, primary_key=True)
    b_code = Column(String)
Run Code Online (Sandbox Code Playgroud)

由于我们使用了声明式,因此我们实际上没有表实例可供使用,这对下一部分是必要的.有很多方法可以访问这些表,但我喜欢的方法是使用sqlalchemy映射内省方法,因为无论类如何映射都可以使用.

from sqlalchemy.orm.attributes import manager_of_class
a_table = manager_of_class(TableA).mapper.mapped_table
b_table = manager_of_class(TableB).mapper.mapped_table
Run Code Online (Sandbox Code Playgroud)

接下来,我们需要一个实际的sql表达式来表示我们感兴趣的数据.这是一个union,它产生的列看起来与第一个类中定义的列相同,id并且a_code.我们可以重命名它,但这不是示例中非常重要的部分.

ab_view_sel = sqlalchemy.alias(a_table.select().union(b_table.select()))
Run Code Online (Sandbox Code Playgroud)

最后,我们将一个类映射到此.可以为此使用声明,但实际上更多的代码是这样做而不是经典的映射样式,而不是更少.请注意,该类继承自object而不是base

class ViewAB(object):
    pass

sqlalchemy.orm.mapper(ViewAB, ab_view_sel)
Run Code Online (Sandbox Code Playgroud)

这就是它.当然这有一些限制; 最明显的是没有(微不足道的)方法来保存ViewAB回数据库的实例.