Python 映射a';假';炼金术中的对象

Python 映射a';假';炼金术中的对象,python,orm,mapping,sqlalchemy,Python,Orm,Mapping,Sqlalchemy,我不确定这叫什么,因为这对我来说是新的,但以下是我想做的: 我的数据库中有两个表:TableA和TableB。TableA有一个pk_id和另一个名为_code的字段。TableB有pk b_id和另一个名为b_代码的字段 我在sqlalchemy代码中映射了这些表,它们工作得很好。我想创建第三个名为TableC的对象,它实际上不存在于我的数据库中,但它包含a_代码和b_代码的组合,如下所示: class TableC: a_code = String b_code = String

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

我的数据库中有两个表:TableA和TableB。TableA有一个pk_id和另一个名为_code的字段。TableB有pk b_id和另一个名为b_代码的字段

我在sqlalchemy代码中映射了这些表,它们工作得很好。我想创建第三个名为TableC的对象,它实际上不存在于我的数据库中,但它包含a_代码和b_代码的组合,如下所示:

class TableC:
  a_code = String
  b_code = String
然后我想查询表C,如:

TableC.query.filter(and_(
        TableC.a_code == x,
        TableC.b_code == y)).all()

问题1)这类东西有名字吗?2) 如何进行映射(使用声明式映射会更好)

实际上没有“虚拟表”的概念,但是可以发送一个查询来“连接”多个表中的数据。这可能是你最接近你想要的

例如,在sqlalchemy/elixir中实现这一点的一种方法是(这与您所展示的并不遥远,我们只是不查询“虚拟”表):


这类似于SQL内部联接,在filter语句中有一些限定条件。这不会给您一个sqlalchemy表对象,但会给您一个来自每个实际表的对象列表。

看起来sqlalchemy允许您将任意查询映射到类。e、 g.来自:

usersaddress=sql.join(t_用户、t_地址、,
t_users.c.id==t_addresses.c.user_id)
类用户地址(对象):
定义报告(自我):

return“我并不完全理解您试图表达的查询,不管它是联合、联接还是第三种情况,但除此之外,当然可以映射任意可选择的查询(可以传递到返回行的数据库的任何内容)

我首先假设您需要某种形式的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)
因为我们使用了声明式,所以实际上没有表实例可以从中工作,这对于下一部分来说是必要的。有很多方法可以访问表,但我更喜欢的方法是使用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
接下来,我们需要一个实际的sql表达式来表示我们感兴趣的数据。 这是一个联合,其结果是列的外观与第一个类、
id
a_code
中定义的列相同。我们可以重命名它,但这不是示例中非常重要的部分

ab_view_sel = sqlalchemy.alias(a_table.select().union(b_table.select()))
最后,我们将一个类映射到该类。可以使用声明式,但这样做实际上需要更多的代码,而不是传统的映射样式。请注意,该类继承自
对象
,而不是

class ViewAB(object):
    pass

sqlalchemy.orm.mapper(ViewAB, ab_view_sel)

当然,这也有一些局限性;最明显的是没有(琐碎的)将
ViewAB
实例保存回数据库的方法。

您的问题毫无意义。您不能使用未映射的表或任何东西查询数据库。您的问题有什么奇怪的用途?如果您有N:M关系,请正确建模。否则,您的方法看起来像是被设计破坏了。您正在尝试与t进行斗争假表的数据在哪里?您是指映射到联接查询(这由SQLAlchemy支持)还是要处理内存中的一些数据?
ab_view_sel = sqlalchemy.alias(a_table.select().union(b_table.select()))
class ViewAB(object):
    pass

sqlalchemy.orm.mapper(ViewAB, ab_view_sel)