![](/img/trans.png)
[英]Convert all rows of a Pandas dataframe column to comma-separated values with each value in single quote
[英]Python Django: Is it possible to convert comma separated values in a column and retrieve each value as query set rows
使用 PostgreSQL 時是可能的。 我不確定如何使用其他數據庫后端來實現它。 請注意,您存儲數據的方式並不理想,可以使用更好的解決方案。 下面有 2 個更好的解決方案示例,其中之一是獨立於數據庫的。
假設您有一個 model 定義如下(我已將示例中的不相關字段替換為單個字符字段):
from django.core.validators import validate_comma_separated_integer_list
from django.db import models
class Plan(models.Model):
group = models.CharField(max_length=256)
student_course_records = models.TextField(validators=[validate_comma_separated_integer_list])
鑒於此,您可以通過 Django 的Func
使用 string_to_array 將學生列表轉換為string_to_array
數組:
Plan.objects.annotate(
students=Func(
F('student_course_records'),
Value(','),
function='string_to_array',
output_field=ArrayField(models.IntegerField())
)
)
這將為您的 object 添加一個名為students
的“虛擬”字段。 它將代表一個數組中的所有學生 ID,以后更容易處理。
由於您現在有一個 ID 數組,您可以使用unnest
function 將這些值分解為單獨的記錄:
Plan.objects.annotate(student=Func(Func(F('student_course_records'), Value(','), function='string_to_array', output_field=ArrayField(models.IntegerField())), function='unnest') )
現在,您將擁有單獨的記錄,而不是students
字段,每個記錄都有一個student
值。 請注意, student_course_records
在每條記錄中仍然可用,但您可以使用values
、 values_list
、 only
或exclude
來更改它。
為了簡化編寫這些查詢,您可以繼承Func
class StringToArray(models.Func):
function = 'string_to_array'
def __init__(self, *args, output_field, **kwargs):
super().__init__(*args, output_field=ArrayField(output_field), **kwargs)
class Unnest(models.Func):
function = 'unnest'
arity = 1
然后您的電話將如下所示:
Plan.objects.annotate(
student=Unnest(
StringToArray(
F('student_course_records'),
Value(','),
output_field=models.IntegerField(),
)
)
)
正如我之前所說,這個數據 model 並不理想,因為它需要在每次數據訪問時解析逗號分隔的列表。 更不用說在這個字段上查詢數據的麻煩了。 有 2 種更好的方法:使用ArrayField
代替逗號分隔的文本字段或使用嵌套的 model。 第一個仍然需要 PostgreSQL 數據庫,第二種方法可以與 Django 官方支持的任何數據庫一起使用,但在這種簡單的用例中可能看起來很嘈雜和冗余。 對於第一種方法,您可以將 model 定義為:
class Plan(models.Model):
group = models.CharField(max_length=256)
student_course_records = ArrayField(models.IntegerField())
對於此 model,您的查詢將簡化為:
Plan.objects.annotate(
student=Unnest(F('student_course_records'))
)
在所有情況下, student_course_records
都將表示為一個數組,無需將其轉換為其他任何內容。
第二種方法看起來像:
class Plan(models.Model):
group = models.CharField(max_length=256)
class Student(models.Model):
plan = models.ForeignKey(Plan, related_name='student_course_records', on_delete=models.CASCADE
對於此 model,您的查詢將簡化為:
Student.objects.all()
使用可選的select_related
或values
調用同時從Plan
model 中提取數據。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.