python - SQLAlchemy - 从表定义中删除列
问题描述
假设我想动态设置一个主键。我用一个虚拟键初始化表,因为 SQLAlchemy 似乎需要它。我编写了一个函数,用于根据主索引指定主键,该主索引在所有意图和目的上都表现得像主键。当我试图取消虚拟钥匙时,我的问题就出现了。
我希望能够在表声明后删除我的虚拟键,以便我可以用我的自定义键替换它。但是,我不能仅仅delattr(my_table,'dummy_key')
因为会有其他对虚拟键的引用,例如在my_table.__table__.columns
其他地方可能还有其他地方。
我的问题是,有没有一种好方法可以从表中删除列定义,同时也删除所有这些其他引用?
目前我这样定义表:
Base = declarative_base(cls=DeferredReflection)
class my_table(Base, TableExtension):
__tablename__ = "my_table"
__table_args__ = {'schema': 'my_schema'}
dummy_key = Column(String(), primary_key=True) #false key, just a placeholder, sqlalchemy requires this
TableExtension
添加一个方法:
def set_primary_key(self, column_name, column_type):
self[column_name] = Column(column_type, primary_key=True)
需要帮助编写此函数:
def remove_column(table, col_name):
# what should I do here?
我已经有一个获取新密钥的功能,它可以工作:
column_names, column_types = get_primary_index(table)
我通过继承向表中添加了一个方法来分配新键。
table.set_new_keys(column_names, column_types)
然后以通常的方式反映表格:
Base.prepare(engine)
这里最重要?
的是如何在不对其余表属性做太多手术的情况下删除列引用。任何意见,将不胜感激。
解决方案
SQLAlchemy 没有官方记录的方法来解决这个问题。我深入研究了源代码,这是我学到的:
my_table._columns
是一个ColumnCollection
my_table.columns
是ImmutableColumnCollection
从my_table._columns
my_table.c
是一个捷径my_table.columns
ColumnCollection
remove
定义了接受Column
对象作为参数的方法。所以我对这个问题的解决方案是:
# get the column instance from table object
my_col_instance = [col for col in my_table._columns if col.name == my_column_name][0]
# remove from the ColumnCollection, note that we're removing it from ._columns not .columns
my_table._columns.remove(my_col_instance)
# execute actual ALTER TABLE SQL query to drop the column
推荐阅读
- c - 为什么 malloc(0) 在 Windows 上会导致严重的内存泄漏?
- c++ - 我怎样才能知道向量的实际最大大小?(不使用 std::vector::max_size)
- java - Java 中的图像即将推出 NPE
- typescript - 为什么扩展索引泛型不允许赋值?
- python - Scrapy 选择器在 shell 中工作,但在蜘蛛中不起作用
- javascript - javascript对象字段设置输入值[object Object]而不是float
- php - 在 Gmail 邮件列表 API 中获取发件人电子邮件地址
- python - 将 Python Heroku 与 Firebase 集成
- angular - Promise.then() 不等待
- sql - Postgres/Redshift/SparkSQL 中的 SQL 执行差异