我有一个团队层次结构模型
class Hrc(models.Model):
id = models.UUIDField(default=uuid.uuid4, primary_key=True, unique=True, editable=False)
emp = models.ForeignKey('Employee', on_delete=models.CASCADE, related_name='emp')
mang = models.ForeignKey('Employee', on_delete=models.CASCADE, related_name='mang')
created_on = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['created_on']
由于我想获取特定员工下的层次结构,因此我想使用 CTE。我想在我拥有的 Django 信号之一中编写 CTE。以下是我收到的信号
@receiver(post_save, sender=Employee)
def employeeUpdated(sender, instance, created, **kwargs):
if not created:
//I want to get the hierarchy under an employee (instance in this case). So the
// CTE should be written here
我要写的CTE是
with hierarchy as
(
select emp, mang, 1 as lvl
from hrc
where emp = instance
union all
select child.emp, parent.emp, lvl+1
from hierarchy as parent
join hrc as child
on child.mang = parent.emp
), lvls as (
select lvl, emp
from hierarchy
group by lvl, emp
)
select lvl, STRING_AGG(emp, '') within group (order by emp)
from lvls
group by lvl;
我怎样才能在信号中写入这个cte并得到想要的结果。
应该可以了。它将利用 Django 的“原始 SQL 查询”功能。
使用 %s
根据您的需要更改传递给 SQL 语句的参数。
from django.db import connection
@receiver(post_save, sender=Employee)
def employeeUpdated(sender, instance, created, **kwargs):
if not created:
with connection.cursor() as cursor:
cursor.execute("""
WITH hierarchy
AS (
SELECT emp
,mang
,1 AS lvl
FROM hrc
WHERE emp = %s
UNION ALL
SELECT child.emp
,parent.emp
,lvl + 1
FROM hierarchy AS parent
INNER JOIN hrc AS child ON child.mang = parent.emp
)
,lvls
AS (
SELECT lvl
,emp
FROM hierarchy
GROUP BY lvl
,emp
)
SELECT lvl
,STRING_AGG(emp, '') within
GROUP (
ORDER BY emp
)
FROM lvls
GROUP BY lvl;""",
[instance.pk]
)
row = cursor.fetchall()
# do whatever you need to do with the result