如何在Django中为用户模型加载sql fixture?

时间:2010-03-09 20:32:00

标签: sql django fixtures fixture

有谁知道如何使用sql fixtures为auth.User加载初始数据? 对于我的模特,我刚才有一个< modelname> .sql文件位于一个名为sql的文件夹中,syncdb可以很好地完成它的工作。但我不知道如何为auth.User模型做到这一点。我用Google搜索了,但没有成功。

提前致谢,

阿尔

7 个答案:

答案 0 :(得分:24)

对于SQL fixture,您必须具有auth表的insert语句。您可以使用命令python manage.py sql auth找到auth表的模式。

更简单且与数据库无关的方式(除非你想要运行一些额外的SQL魔法),只需在应用程序的fixtures目录中创建一个JSON或YAML fixture文件,其中包含这样的数据:

- model: auth.user
  pk: 100000
  fields:
    first_name: Admin
    last_name: User
    username: admin
    password: "<a hashed password>"

您可以在django shell中快速生成哈希密码

>>> from django.contrib.auth.models import User
>>> u = User()
>>> u.set_password('newpass')
>>> u.password
'sha1$e2fd5$96edae9adc8870fd87a65c051e7fdace6226b5a8'

只要您运行syncdb,就会加载。

答案 1 :(得分:8)

您正在寻找loaddata

manage.py loadata path/to/your/fixtureFile

但我认为该命令只能处理XML,YAML,Python或JSON格式的文件(see here)。要创建适当的文件,请查看dumpdata方法。

答案 2 :(得分:4)

感谢您的回答。我找到了适用于我的解决方案,巧合是Brian的建议之一。这是:

我在syncdb之后断开了创建超级用户的信号,因为我的auth_user fixture中有我的超级用户:

<强> models.py

from django.db.models import signals
from django.contrib.auth.management import create_superuser
from django.contrib.auth import models as auth_app


signals.post_syncdb.disconnect(
    create_superuser,
    sender=auth_app,
    dispatch_uid = "django.contrib.auth.management.create_superuser")

然后我创建了一个在syncdb之后调用的信号:

<强>&LT; myproject&gt; /&lt; myapp&gt; / management / __ init __。py

"""
Loads fixtures for files in sql/<modelname>.sql
"""
from django.db.models import get_models, signals
from django.conf import settings 
import <myproject>.<myapp>.models as auth_app

def load_fixtures(app, **kwargs):
    import MySQLdb
    db=MySQLdb.connect(host=settings.DATABASE_HOST or "localhost", \
       user=settings.DATABASE_USER,
    passwd=settings.DATABASE_PASSWORD, port=int(settings.DATABASE_PORT or 3306))

    cursor = db.cursor()

    try:
        print "Loading fixtures to %s from file %s." % (settings.DATABASE_NAME, \
            settings.FIXTURES_FILE)
        f = open(settings.FIXTURES_FILE, 'r')
        cursor.execute("use %s;" % settings.DATABASE_NAME)
        for line in f:
            if line.startswith("INSERT"):
                try:
                    cursor.execute(line)
                except Exception, strerror:
                    print "Error on loading fixture:"
                    print "-- ", strerror
                    print "-- ", line

        print "Fixtures loaded"

    except AttributeError:
        print "FIXTURES_FILE not found in settings. Please set the FIXTURES_FILE in \
            your settings.py" 

    cursor.close()
    db.commit()
    db.close()

signals.post_syncdb.connect(load_fixtures, sender=auth_app, \
    dispatch_uid = "<myproject>.<myapp>.management.load_fixtures")

在我的 settings.py 中,我添加了FIXTURES_FILE以及带有sql转储的.sql文件的路径。

我还没有找到的一件事是如何在创建表之后才触发此信号,而不是每次触发syncdb时触发此信号。暂时解决这个问题的方法是在我的sql命令中使用INSERT IGNORE INTO。

我知道这个解决方案远非完美,非常欢迎评论家/改进/意见!

此致

阿尔

答案 3 :(得分:4)

有一个技巧:(在Django 1.3.1上测试)

<强>解决方案:

  1. python manage.py startapp auth_fix
  2. mkdir auth_fix/fixtures
  3. python manage.py dumpdata auth > auth_fixtures/fixtures/initial_data.json
  4. Include auth_fix in INSTALLED_APPS inside settings.py
  5. 下次运行python manage.py syncdb时,Django会自动加载auth fixture。

    <强>解释

    1. 只需创建一个空的应用程序来保存fixtures文件夹。在其中留下__init__py,models.py和views.py,以便Django将其识别为应用而不仅仅是文件夹。
    2. 在应用程序中创建fixtures文件夹。
    3. python manage.py dumpdata auth将在数据库中转储“auth”数据,其中包含所有“组和用户”信息。命令的其余部分只是将输出重定向到名为“initial_data.json”的文件,这是Django在运行“syncdb”时查找的文件。
    4. 只需在settings.py内的INSTALLED_APPS中包含auth_fix。
    5. 此示例显示了如何在JSON中执行此操作,但您基本上可以使用您选择的格式。

答案 4 :(得分:3)

一个选项是手动导入auth.User SQL,然后将其转储到标准的Django fixture(如果你想让syncdb找到它,请将其命名为initial_data)。您通常可以将此文件放入任何应用程序的灯具目录中,因为固定数据将全部使用正确的app_label键入。或者您可以创建一个空/虚拟应用程序并将其放在那里。

另一个选项是覆盖syncdb命令并以您认为合适的方式应用夹具。

我同意Felix的观点,Django中没有非常重要的自然钩子用于使用SQL填充contrib应用程序。

答案 5 :(得分:3)

如果您正在使用south进行数据库迁移,则创建用户非常简单。

首先,创建一个裸数据迁移。它需要包含在某些应用程序中。如果您有一个共享代码的公共应用程序,那将是一个不错的选择。如果你有一个专注于用户相关代码的应用程序,那就更好了。

$ python manage.py datamigration <some app name> add_users

相关的迁移代码可能如下所示:

# encoding: utf-8
import datetime
from south.db import db
from south.v2 import DataMigration
from django.db import models
from django.contrib.auth.models import User

class Migration(DataMigration):

    users = [
        {
            'username': 'nancy',
            'email': 'nancy@example.com',
            'password': 'nancypassword',
            'staff': True,
            'superuser': True
        },
        {
            'username': 'joe',
            'email': '',
            'password': 'joepassword',
            'staff': True,
            'superuser': False
        },
        {
            'username': 'susan',
            'email': 'susan@example.com',
            'password': 'susanpassword',
            'staff': False,
            'superuser': False
        }
    ]

    def forwards(self, orm):
        """
        Insert User objects
        """
        for i in Migration.users:
            u = User.objects.create_user(i['username'],  i['email'], i['password'])
            u.is_staff = i['staff']
            u.is_superuser = i['superuser']
            u.save()

    def backwards(self, orm):
        """
        Delete only these users
        """
        for i in Migration.users:
            User.objects.filter(username=i['username']).delete()

然后只需运行迁移,就应插入auth用户。

$ python manage.py migrate <some app name>

答案 6 :(得分:1)

我只是将SQL语句添加到另一个模型的自定义sql文件中。我选择了我的Employee模型,因为它依赖于auth_user。 我编写的自定义SQL实际上是从我的遗留应用程序中读取并从中提取用户信息,并使用REPLACE而不是INSERT(我正在使用MySQL)所以我可以随时运行它。 我将REPLACE ... SELECT语句放在一个过程中,以便手动运行或使用cron安排。