【问题标题】:SQLAlchemy ORM get rid of global metadataSQLAlchemy ORM 摆脱全局元数据
【发布时间】:2017-05-10 03:10:55
【问题描述】:

一个示例程序:

from sqlalchemy import Column, String, Table, select
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()

class Dog(Base):
    __tablename__ = "kennel"
    name = Column(String, primary_key=True)

    def get_table(self):
        return Table(self.name, self.metadata, Column('bone', String))

示例用法:

def f():
    spot = Dog("Spot")
    spot_stash = spot.get_table()

f()
f()

例外:

InvalidRequestError: 表 'Spot' 已为此元数据定义 实例。指定 'extend_existing=True' 重新定义选项和 现有 Table 对象上的列。

我不能连续调用函数f() 两次,因为元数据是全局的。我不想“extend_existing”,只是从程序的不同位置调用一个独立的函数。我看不到如何使 Base 成为非全局的,因为静态类声明依赖于它。有没有办法使用如此庞大的全局变量?

【问题讨论】:

  • get_table() 函数的用途是什么?你可以解释吗。有什么用例吗?
  • @Laurent LAPORTE ...因此,对于狗窝中的每只狗,我想取每只狗的桌子,他放骨头的地方并添加一个 t 骨。稍后在程序中,我想重新创建狗并再次获取它们各自的表以进行另一次操作。
  • 对不起,我迷路了。 “取每只狗的桌子”是什么意思,你说的是记录吗?
  • @Laurent LAPORTE 每只狗都是一个复杂的产品,有许多与之关联的表,更像是整个数据库。它们跨越数百万行数据,并为我们公司的每条狗提供略有不同的列集。

标签: python orm sqlalchemy


【解决方案1】:

您似乎试图获取与Dog 类关联的表,但实际上是在您的get_table() 方法中创建一个 Table。这就是为什么它抱怨当前数据库中已经存在一个 Table

【讨论】:

  • 我实际上并没有调用 Table.create()。它已经创建并存在于数据库中,我只需要访问它。我可以将它从数据库中“反射”回来,但这会很慢,尤其是考虑到程序已经可以访问表定义。
  • @Muposat 您误将在 SQL 中创建表与创建 Table 对象相混淆。创建Table 对象的行为会将该表添加到指定的metadata,从而导致此冲突。
  • @univerio 我知道这一点。 jknupp 声称“它在抱怨当前数据库中已经存在一个表”,这是不正确的。
猜你喜欢
  • 1970-01-01
  • 2015-12-21
  • 1970-01-01
  • 1970-01-01
  • 2013-03-14
  • 2019-12-31
  • 1970-01-01
  • 1970-01-01
  • 2022-01-21
相关资源
最近更新 更多