SQLAlchemy-从表定义中删除列

时间:2018-08-27 19:16:01

标签: 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)

这里的大?是如何在不对其余表属性进行大量操作的情况下删除列引用的。任何建议将不胜感激。

2 个答案:

答案 0 :(得分:2)

SQLAlchemy 没有针对此问题的官方文档记录方法。我深入研究了源代码,这是我学到的:

  1. my_table._columns 是一个 ColumnCollection
  2. my_table.columns 是从 ImmutableColumnCollection
  3. 生成的 my_table._columns
  4. my_table.cmy_table.columns
  5. 的快捷方式

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

答案 1 :(得分:1)

深入了解SQLAlchemy的源代码之后,可能没有任何官方方法可以满足您的需求。

尝试后,我发现一种看似有效的方法(无法保证稳定)

通过s = '$100.99' s1 = re.sub('\$([0-9]+\.?[0-9]*)', '\g<1> dollars', s) print(s1) # 100.99 dollars 从表类中获取元数据,并通过table_meta = my_table.metadata.tables[my_table.__tablename__]修改table_meta._cloumns

这在查询table_meta._cloumns.remove(table_meta._cloumns['dummy_key'])中对我有用,希望对您有所帮助。