Django:如何获取项目中每个表及其所有列?
我正在用MySQL的INTO OUTFILE和LOAD DATA LOCAL INFILE来创建一套完整的数据库复制脚本。
具体来说:
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),所以使用平面文件的方法似乎是唯一合理的方式来在MySQL中进行这么大的复制。我已经把数据库结构复制过来了(使用./manage.py syncdb --migrate),我现在遇到的问题主要是复制数据,这需要我有表和列的信息,以便创建正确的SQL语句。另外,我不能使用默认的列顺序,因为我复制的生产数据库的列顺序与新建的syncdb生成的顺序不同(这主要是因为经过了几个月的迁移和结构变化)。
3 个回答
你有没有了解过“manage.py dumpdata”和“manage.py loaddata”?这两个命令可以把数据导出和导入,格式是json。 我用它来把一个网站的数据导出来,然后覆盖到另一个网站的数据库里。虽然在dumpdata的时候没有“导出所有数据库”的选项,但你可以在“manage.py dbshell”命令的结果上用循环来调用它。
你有没有看过 manage.py 这个文件?
你可以获取很多关于SQL的信息,比如说,如果你想要查看你项目中某个应用的所有创建表的语法,你可以这样做:
python manage.py sqlall <appname>
如果你输入:
python manage.py help
你会发现还有很多其他的功能。
我深入研究了源代码,找到了这个解决方案。我觉得可能还有更好的方法,但这个方法可以解决问题。
第一个代码块获取了所有普通的(非多对多)表及其列。
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))
接下来的代码块是比较棘手的部分。它获取了所有多对多字段的表及其列。
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))