假设我要动态设置主键。我用虚拟密钥初始化表,因为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)
这里的大?
是如何在不对其余表属性进行大量操作的情况下删除列引用的。任何建议将不胜感激。
答案 0 :(得分:2)
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
答案 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'])
中对我有用,希望对您有所帮助。