SQLAlchemy重新映射类

问题描述 投票:0回答:1

我有一个问题,在更改数据库中的相应表后(可能会添加或删除列),我需要重新映射类。

最小示例:

from sqlalchemy import MetaData, Column, Integer, Table, ForeignKey
from sqlalchemy.orm import mapper
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()
Base.metadata = MetaData()


class TableOne(Base):
    __tablename__ = "tableone"
    id = Column(Integer, primary_key=True)


class DynamicTable(object):
    pass


def get_dynamic_table(columns):
    return Table(
        "dynamictable",
        Base.metadata,
        Column("id", Integer, primary_key=True),
        Column("tableone_id", ForeignKey("tableone.id")),
        *[Column(name, type) for name, type in columns],
    )


config = {}
config["dynamic_columns"] = [("foo", Integer)]
initial_table = get_dynamic_table(config["dynamic_columns"])
mapper(DynamicTable, initial_table)

# Run a lot of queries involving e.g. session.query(getattr(DynamicTable, config[dynamic_columns][0]))

# Change config

config["dynamic_columns"] = [("bar", Integer)]

# .. rebuild dynamictable in backend with new config ...

# Now, DynamicTable doesn't reflect the database table

Base.metadata.remove(initial_table)  # Removes the table from metadata, but not the mapper..
updated_table = get_dynamic_table(config["dynamic_columns"])
mapper(DynamicTable, updated_table) # Raises sqlalchemy.exc.ArgumentError

完整读取错误消息

Traceback (most recent call last):
  File "test.py", line 45, in <module>
    mapper(DynamicTable, updated_table)
  File "<string>", line 2, in mapper
  File "/dist/ella-python/lib/python3.7/site-packages/sqlalchemy/orm/mapper.py", line 694, in __init__
    self._configure_class_instrumentation()
  File "/dist/ella-python/lib/python3.7/site-packages/sqlalchemy/orm/mapper.py", line 1220, in _configure_class_instrumentation
    self.class_)
sqlalchemy.exc.ArgumentError: Class '<class '__main__.DynamicTable'>' already has a primary mapper defined. Use non_primary=True to create a non primary Mapper.  clear_mappers() will remove *all* current mappers from all classes.

是否有任何方法可以重新映射此(或可能所有)表?

python sqlalchemy
1个回答
0
投票

Mapperdispose()上有未公开的方法。在clear_mappers中使用它,它对使用有一些严格的警告,但是以下似乎有效

clear_mappers
© www.soinside.com 2019 - 2024. All rights reserved.