我有一种情况,我必须在删除之前归档其他表中的表的数据。
让我们说,我有用户表,它的归档表为user_archive,使用与用户相同的签名创建,只有在以下函数中更改了表名:
def create_all_archive(db, bind="__all__", operation="create_all", skip_tables=False):
"""Create archive for all the tables
:param db: Database connection
:param app: Current application for which to create tables
:param bind: Database bind
:param operation: Operation, default "create_all"
:param skip_tables: True if to be skipped else False
:return:
"""
app = db.get_app()
if bind == '__all__':
binds = [None] + list(app.config.get('SQLALCHEMY_BINDS') or ())
elif isinstance(bind, string_types) or bind is None:
binds = [bind]
else:
binds = bind
for bind in binds:
extra = {}
if not skip_tables:
tables = db.get_tables_for_bind(bind)
tables_copy = [copy.deepcopy(table) for table in tables]
for table in tables_copy:
table.name = "{}_archive".format(table.name)
extra['tables'] = tables_copy
op = getattr(db.Model.metadata, operation)
op(bind=db.get_engine(app, bind), **extra)
我在应用程序启动期间将此函数与db.create_all()一起调用,如下所示:
def create_tables(db):
"""Creates all the schema tables as defined in models
:param db: database connection
:return:
"""
db.create_all()
create_all_archive(db)
我的用户删除成员功能如下:
def delete_user(self):
"""Delete user
:return: Deleted user
"""
import copy
user = copy.deepcopy(self)
user.__tablename__ = self.__archive_tablename__
db.session.delete(self)
session_commit()
db.session.add(user)
session_commit()
return self
这里我使用深层复制将整个用户对象复制到另一个对象,然后如上所述更改表的名称。但是当用户被添加到会话中然后调用commit时,它不会给出任何错误,但甚至不会将user
的值存储在user_archive
表中。
__archive_tablename__
是一个declared_attr
,我在mixin中提供了以下归档表名称:
class ArchiveMixin(object):
"""Mixin class to add history table and perform operations on history table
"""
@declared_attr
def __archive_tablename__(cls):
return "{}_archive".format(cls.__tablename__.lower())
这甚至可能吗?如果是,那么我在这里缺少什么?
注意:我通过使用两个不同的数据库会话来解决所有这些问题,一个用于实时数据,另一个用于存档数据和 具有相同的表定义在两个会话中都有效。但在那 案例档案数据将在完全不同的数据库中。一世 希望它在同一个数据库中。那么,有可能吗?
使用的数据库: MariaDB