有没有办法使用Django为SQL表概念指定列的创建顺序?

qoefvg9y  于 2022-09-21  发布在  Go
关注(0)|答案(2)|浏览(303)

我目前正在使用Django模型重新生成一个旧的PostgreSQL数据库。数据库的第一个版本有一些脚本来计算数据以填充表。

我想要插入到表中的数据被格式化为TSV文件:value1\tvalue2\value3。接下来将使用SQL命令\copy my_table from 'path/to/my/file.tsv' with null as 'NULL'插入它们。

因为脚本定义了TSV文件中数据的顺序,所以我的字段必须在表中以相同的顺序创建。问题是, Django 似乎把外键放在了table的最后。

此模型示例:

class My_table(models.Model):
    field1 = models.CharField(primary_key=True, max_length=25)
    field2 = models.ForeignKey(....)
    field3 = models.IntegerField(blank=True, null=True)
    field4 = models.CharField(max_length=2000, blank=True, null=True)

可以给出这样一张表:

field1 | field3 | field4 | field2  
 --------+--------+--------+--------

我想要的是:

field1 | field2 | field3 | field4  
 --------+--------+--------+--------

有没有办法得到这样的结果?

6ie5vjzr

6ie5vjzr1#

如果您正在使用内置的Django迁移,您实际上可以对迁移文件中定义的fields重新排序,以更改在数据库中创建列的顺序。

您应该有类似于以下内容的内容:


# 0001_initial.py

class Migration(migrations.Migration):
    ....
    operations = [
        migrations.CreateModel(

            # the fields here can be re-ordered
            fields=[
                ('id', ...),
                ('field1', ....),
                ('field2', ....),
                ('field3', ....),
                ('field4', ....),
            ]
        )
    ]

您可以使用python manage.py sqlmigrate appname 0001打印出要执行的SQL:

CREATE TABLE "my_table" ("id", ....);

请注意,无论字段排序如何,Django都会强制将“id”作为表中定义的第一列。

j8yoct9x

j8yoct9x2#

我查看了一个Django代码,它看起来像是在Make-Migration运行期间,首先添加所有普通字段,然后添加一个带有关系的字段(这样,外键字段就变成了最后一个)。

因此,如果不修改Django本身,似乎就没有简单的解决方案。因此,手动更改0001_initial.py似乎是唯一的选择。

但对于大量型号,手动更改现场顺序也不是一个可维护的选项。因此,这里有一个自动设置模型订单的小技巧。

将以下内容添加到0001_initial.py文件的末尾,并将db.models更改为您的型号:


# import your models

import db.models as my_models

# Change field order to one in model

for op in Migration.operations:
    if isinstance(op, migrations.CreateModel):
        Model = getattr(my_models, op.name)
        fields = {field_tuple[0]: field_tuple for field_tuple in op.fields}
        new_fields = []
        for field in Model.__dict__:
            if field in fields:
                new_fields.append(fields[field])
        op.fields = new_fields

此代码根据原始模型中的属性顺序更改migrations.CreateModel中的顺序。

仍然不是很棒,但至少不需要手动完成。只需在末尾添加一些代码即可。

相关问题