Den*_*ach 8 python orm sqlalchemy
我有很多模型类,它们之间有关系,需要编辑CRUD接口.问题是某些对象无法删除,因为有其他对象引用它们.有时我可以设置ON DELETE规则来处理这种情况,但在大多数情况下,我不希望自动删除相关对象,直到它们被手动解除绑定.无论如何,我想向编辑器呈现一个引用当前查看对象的对象列表,并突出显示那些因FOREIGN KEY约束而无法删除的对象.是否有自动发现引用的现成解决方案?
更新
这个任务似乎很常见(例如django ORM显示所有依赖关系),所以我想知道它还没有解决方案.
建议有两个方向:
backref.但并不能保证所有关系都已backref定义.而且,有些情况下backref毫无意义.虽然我可以在任何地方定义它,但我不喜欢这样做而且它不可靠.MetaData对象表并从其foreign_keys属性中收集依赖关系(sqlalchemy_schemadisplay的代码可以用作示例,感谢stephan的评论).这将允许捕获表之间的所有依赖关系,但我需要的是模型类之间的依赖关系.一些外键在中间表中定义,并且没有与它们对应的模型(secondary在关系中使用).当然,我可以走得更远并找到相关的模型(必须找到一种方法来做到这一点),但它看起来太复杂了.解
下面是我用作解决方案的基本模型类(为声明性扩展而设计)的方法.它并不完美,不符合我的所有要求,但它适用于我项目的当前状态.结果被收集为字典字典,因此我可以通过对象及其属性显示它们.我没有带还未决定它是否是好主意,因为参照网址列表有时是巨大的,我不得不把它限制在一个合理的数值.
def _get_referers(self):
db = object_session(self)
cls, ident = identity_key(instance=self)
medatada = cls.__table__.metadata
result = {}
# _mapped_models is my extension. It is collected by metaclass, so I didn't
# look for other ways to find all model classes.
for other_class in medatada._mapped_models:
queries = {}
for prop in class_mapper(other_class).iterate_properties:
if not (isinstance(prop, PropertyLoader) and \
issubclass(cls, prop.mapper.class_)):
continue
query = db.query(prop.parent)
comp = prop.comparator
if prop.uselist:
query = query.filter(comp.contains(self))
else:
query = query.filter(comp==self)
count = query.count()
if count:
queries[prop] = (count, query)
if queries:
result[other_class] = queries
return result
Run Code Online (Sandbox Code Playgroud)
感谢所有帮助过我的人,尤其是斯蒂芬和范.
SQL:我绝对不同意S.Lott的回答.我不知道开箱即用的解决方案,但绝对有可能发现所有具有ForeignKey约束的表到给定的表.人们需要用正确的INFORMATION_SCHEMA观点,如REFERENTIAL_CONSTRAINTS,KEY_COLUMN_USAGE,TABLE_CONSTRAINTS,等见的SQL Server实例.有了一些限制和扩展,大多数版本的新关系数据库都支持INFORMATION_SCHEMA标准.当您拥有表中的所有FK信息和对象(行)时,需要运行一些SELECT语句来获取其他表中引用给定行的所有其他行并防止其被删除.
SqlAlchemy:正如stephan在他的评论中指出的那样,如果你使用ormwith backreffor relationship,那么你应该很容易得到父对象的列表,这些对象继续引用你想要删除的对象,因为这些对象基本上是映射的对象的属性(child1.Parent).
如果你使用Tablesql炼金术的对象(或者不总是backref用于关系),那么你必须获得foreign_keys所有表的值,然后对于所有那些ForeignKey调用references(...)方法,将表作为参数.通过这种方式,您将找到所有引用您的对象映射到的表的FK(和表).然后,您可以通过为每个FK构建查询来查询所有引用对象的对象.
| 归档时间: |
|
| 查看次数: |
1267 次 |
| 最近记录: |