我不確定這是否符合最佳做法,但我發現Alembic
會通知我__table_args__
中的索引,但實際上在遷移期間並不適合我。我製作了這個小腳本,可以生成在__table_args__
屬性中找到的新索引。如上所述,它使用Index.create()
,但如果它們不存在,將生成新的索引。
def create_indexes(db, drop_index=False):
"""
Creates all indexes on models in project if they do not exists already. Assumes all models
inherit from RequiredFields class, otherwise will need to adjust search for subclasses. If the index
exists SQLAlchemy throws an error and we assume everything is ok.
:param db: The app db object, acts as the engine param for the Index.create()
:param drop_index: specifies whether the indexes should be dropped or created
:return:
"""
from application.base_models import RequiredFields
from sqlalchemy import Index
from sqlalchemy.exc import ProgrammingError
for klass in RequiredFields.__subclasses__():
if hasattr(klass, '__table_args__'):
for item in getattr(klass, '__table_args__'):
if isinstance(item, Index):
try:
if not drop_index:
item.create(db.engine)
else:
item.drop(db.engine)
except ProgrammingError: # If index exists, creation fails on error
pass
return
這裏是表示索引的示例類。
class MyModel(RequiredFields):
__table_args__ = (
db.Index(...),
db.Index(...),
)
對不起,這個回答是錯誤的。 ALTER TABLE不用於索引。 SQLAlchemy的支持「CREATE INDEX」非常直接地使用'Index.create()',以及用'CreateIndex' DDL構建更復雜的腳本的情況。沒有必要抓住「create_all()」輸出或類似的東西。 – zzzeek
謝謝指出。我同意 - 我描述瞭如何實施和支持有問題的方法。並且完全忘記了簡單快捷的'index.create'。 – vvladymyrov