在应用程序中使用Django和PostgreSQL控制列级权限逻辑的最佳位置

b4wnujal  于 3个月前  发布在  PostgreSQL
关注(0)|答案(1)|浏览(66)

我正在构建一个应用程序,它允许用户创建表,并为每个列上的其他用户设置权限(如果需要)。这些表需要可审计,以便用户可以询问:

  • 谁做了改变,
  • 当;
  • 和它们是什么-这是为了支持一个不同的功能。

用户还可以向表中添加列,我希望能够自动化所有这些:创建表,列的权限,更改表以添加新列,创建触发器等。
我正在使用触发器函数设置审计表自动化。我开始将权限逻辑写入触发器函数,但当我的方法开始变得笨拙时停止了:

  • 使用hstore遍历列标题(https://dbfiddle.uk/sRJf7ZBm);
  • 如果用户对每一列都有权限,则将插入存储在一个字符串(https://dbfiddle.uk/gE5bqKWe)中,以便添加-我还担心这会对类型产生什么影响(除了文本,我还有其他类型);
  • 我不知道如何使用事务来提交或回滚,如果发生错误,显然这是唯一可能的过程?
  • 我甚至在考虑为每列创建一个新表并将它们连接在一起,但我担心这会产生其他问题,可能会降低性能?

我知道postgres有能力通过列设置用户对表的权限,似乎使用数据库权限系统会是更健壮的方法,但我不知道是否有可能使用django的身份验证系统来做到这一点。
Django内置的身份验证系统为用户创建了表,而实际上并没有在数据库中创建用户。现在,我只使用postgres用户与数据库交互。这意味着控制权限的唯一方法是通过触发器函数或在python应用程序代码本身。
任何一个表的行数都不会超过100 k,在大多数情况下都不会超过1 k。
我是postgres和数据库的新手,所以我担心在错误的开发道路上走得太远。任何帮助都非常感谢!

2w3kk1z5

2w3kk1z51#

使用PostgreSQL在Django应用程序中构建动态和可审计的表系统确实具有挑战性,特别是如果您是数据库新手。您的项目涉及多个层次:动态表创建,基于列的权限,审计更改,并将其与Django的身份验证系统集成。让我们分解您的需求并为每个需求提供策略:

1.动态表创建和修改方式:与其为每个用户定义的表创建物理表,不如考虑使用更灵活的模式。一种常见的方式是EAV模型,可以存储不同的“实体”(您的动态表)和它们的“属性”(列)在一个更通用的结构。更易于动态管理,尤其是在添加新列或表时。
2.基于列的权限管理方法:在PostgreSQL中管理列级别的权限可能会变得复杂。相反,在Django应用程序中处理此逻辑。创建一个权限模型,将用户,表和列联系在一起,指定每个用户可以对每个列做什么。好处:更容易与Django的身份验证系统集成,更灵活。
**3.审计(变更跟踪)**方法:使用单独的审计表甚至单独的模式来跟踪变更。您可以在PostgreSQL中使用触发器来记录此审计表的变更。或者,在Django中使用post_保存和post_delete事件的信号侦听器来处理此问题。好处:提供清晰的变更历史,而不会弄乱主数据表。
4.在PostgreSQL中使用Django关注点:Django内置的auth系统不会创建数据库级别的用户,这使得使用PostgreSQL的原生列级别权限变得复杂。解决方案:在Django应用中处理权限。使用Django的用户和组系统在应用级别定义和检查权限。实现策略架构设计:为你的用户自定义表实现一个EAV模型或类似的灵活结构。审核模型:创建一个Django模型来存储用户对这些动态表的每一列的权限。通过PostgreSQL触发器或Django信号实现审计日志记录。用户身份验证和授权:利用Django的用户身份验证和组系统来管理应用程序级别的访问和权限。
使用Django信号进行审计跟踪的示例代码以下是如何使用Django信号实现审计日志的示例:

from django.db.models.signals import post_save
from django.dispatch import receiver
from yourapp.models import YourDynamicModel, AuditLog

@receiver(post_save, sender=YourDynamicModel)
def log_change(sender, instance, **kwargs):
    AuditLog.objects.create(
        table_name=sender.__name__,
        row_id=instance.pk,
        changed_data={...} # Capture the changed data here
    )

字符串

备注:

  • 性能考虑因素:EAV模型的性能可能不如传统的关系模型,但对于您的数据大小(高达100k行),这可能不是一个重大问题。
  • 复杂性:这种方法简化了某些方面(如动态模式更改和权限管理),但增加了其他方面(如查询和数据完整性)的复杂性。
  • 可伸缩性:随着应用程序的增长,您可能需要重新访问和优化架构的某些部分。

这个策略平衡了灵活性和你需求的复杂性,并与Django的功能和你对它的熟悉程度很好地保持一致。记住,每个架构决策都有权衡,所以随着应用程序的发展,不断评估这种方法是否仍然是最适合的是很重要的。

相关问题