Django:如何在项目中获取每个表和所有表的列?

时间:2010-07-08 20:44:40

标签: python django

我正在使用MySQL的INTO OUTFILE和LOAD DATA LOCAL INFILE创建一组SQL完整数据库副本脚本。

具体做法是:

SELECT {columns} FROM {table} INTO OUTFILE '{table}.csv'

LOAD DATA LOCAL INFILE '{table}.csv' REPLACE INTO {table} {columns}

因此,我不需要表格,我还需要表格的列。

我可以获取所有表和列,但这不包括m2m表:

from django.db.models import get_models()
for model in get_models():
    table = model._meta.db_table
    columns = [field.column for field in model._meta.fields]

我也可以获得所有表格,但这不能让我访问列:

from django.db import connection
tables = connection.introspection.table_names()

如何为Django项目获取该表上的每个表和每个相应的列?

更多详情:

我在一个相当大的数据集(> 1GB)上这样做,所以使用flat file方法似乎是在MySQL中制作这么大的副本的唯一合理方法。我已经复制了模式(使用./manage.py syncdb --migrate),而我遇到的问题是复制数据,这要求我使用表和列来创建正确的SQL语句。此外,我不能使用默认列排序的原因是因为我正在复制的生产数据库具有与使用新syncdb创建的不同的列排序(由于数月的迁移和模式更改)。

3 个答案:

答案 0 :(得分:6)

你看过manage.py吗?

您可以获取大量SQL信息,例如,为您的项目中的应用程序获取所有创建表语法:

python manage.py sqlall <appname>

如果输入:

python manage.py help

你可以看到很多其他功能。

答案 1 :(得分:3)

我挖到了源头找到了这个解决方案。我觉得可能有更好的方法,但这就是诀窍。

第一个块获取所有正常(非m2m)表及其列

from django.db import connection
from django.apps import apps

table_info = []
tables = connection.introspection.table_names()
seen_models = connection.introspection.installed_models(tables)
for model in apps.get_models():
    if model._meta.proxy:
        continue

    table = model._meta.db_table
    if table not in tables:
        continue

    columns = [field.column for field in model._meta.fields]
    table_info.append((table, columns))

下一个块是棘手的部分。它获取所有m2m字段表及其列。

for model in apps.get_models():
    for field in model._meta.local_many_to_many:
        if not field.creates_table:
            continue

        table = field.m2m_db_table()
        if table not in tables:
            continue
        columns = ['id'] # They always have an id column
        columns.append(field.m2m_column_name())
        columns.append(field.m2m_reverse_name())
        table_info.append((table, columns))

答案 2 :(得分:0)

您是否查看过“manage.py dumpdata”和“manage.py loaddata”?它们以json格式转储和加载。我用它来从一个站点转储东西并覆盖另一个站点的数据库。它在dumpdata上没有“every database”选项,但您可以在“manage.py dbshel​​l”命令的结果中循环调用它。