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

发布于 2024-08-24 16:21:11 字数 183 浏览 10 评论 0原文

有谁知道如何使用 sql 夹具加载 auth.User 的初始数据? 对于我的模型,我只需要有一个 < modelname >.sql 文件位于名为 sql 的文件夹中,syncdb 完美地完成了它的工作。但我不知道如何为 auth.User 模型做到这一点。我用谷歌搜索过,但没有成功。

提前致谢,

奥尔多

Does anyone knows how to load initial data for auth.User using sql fixtures?
For my models, I just got have a < modelname >.sql file in a folder named sql that syncdb does it's job beautifully. But I have no clue how to do it for the auth.User model. I've googled it, but with no success.

Thanks in advance,

Aldo

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

梓梦 2024-08-31 16:21:11

对于 SQL 固定装置,您必须专门为 auth 表添加插入语句。您可以使用命令 python manage.py sql auth 找到 auth 表的架构。

更简单且独立于数据库的方法(除非您想要运行一些额外的 SQL 魔法),就是制作 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 时都会加载它。

For SQL fixtures, you'd have to specifically have insert statements for the auth tables. You can find the schema of the auth tables with the command python manage.py sql auth.

The much easier and database-independent way (unless you have some additional SQL magic you want to run), is to just make a JSON or YAML fixture file in the fixtures directory of your app with data like this:

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

You can generate a hashed password quickly in a django shell

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

This will get loaded whenever you run syncdb.

氛圍 2024-08-31 16:21:11

您正在寻找 loaddata

manage.py loadata path/to/your/fixtureFile

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

You are looking for loaddata:

manage.py loadata path/to/your/fixtureFile

But I think the command can only deal with files in XML, YAML, Python or JSON format (see here). To create such appropriate files, have a look at the dumpdata method.

↙温凉少女 2024-08-31 16:21:11

感谢您的回答。我找到了适合我的解决方案,巧合的是布莱恩的建议之一。首先,

我断开了在syncdb之后创建超级用户的信号,因为我的超级用户在我的auth_user固定装置中:

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之后调用的信号:

<强><我的项目>>/< myapp >/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 。

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

问候,

奥尔多

Thanks for your answers. I've found the solution that works for me, and for coincidence was one of Brian's suggestion. Here it is:

Firs I disconnected the signal that created the Super User after syncdb, for I have my super user in my 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")

Then I created a signal to be called after syncdb:

< myproject >/< myapp >/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")

And in my settings.py I added FIXTURES_FILE with the path to my .sql file with the sql dump.

One thing that I still haven't found is how to fire this signal only after the tables are created, and not everytime syncdb is fired. A temporary work around for this is use INSERT IGNORE INTO in my sql command.

I know this solution is far from perfect, and critics/improvements/opinions are very welcome!

Regards,

Aldo

成熟稳重的好男人 2024-08-31 16:21:11

有一个技巧:(在 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. 在settings.py内的INSTALLED_APPS中包含auth_fix

下次运行python manage.pysyncdb时,Django将自动加载auth固定装置。

说明:

  1. 只需创建一个空应用程序来保存灯具文件夹。将 __init__py、models.py 和views.py 保留在其中,以便 Django 将其识别为应用程序而不仅仅是文件夹。
  2. 在应用程序中创建fixtures文件夹。
  3. python manage.py dumpdata auth 将转储数据库中的“auth”数据以及所有组和用户信息。该命令的其余部分只是将输出重定向到名为“initial_data.json”的文件中,该文件是 Django 在运行“syncdb”时查找的文件。
  4. 只需将 auth_fix 包含在 settings.py 内的 INSTALLED_APPS 中即可。

此示例展示了如何在 JSON 中执行此操作,但您基本上可以使用您选择的格式。

There is a trick for this: (tested on Django 1.3.1)

Solution:

  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

Next time you run python manage.py syncdb, Django will load the auth fixture automatically.

Explanation:

  1. Just make an empty app to hold the fixtures folder. Leave __init__py, models.py and views.py in it so that Django recognizes it as an app and not just a folder.
  2. Make the fixtures folder in the app.
  3. python manage.py dumpdata auth will dump the "auth" data in the DB with all the Groups and Users information. The rest of the command simply redirects the output into a file called "initial_data.json" which is the one that Django looks for when you run "syncdb".
  4. Just include auth_fix in INSTALLED_APPS inside settings.py.

This example shows how to do it in JSON but you can basically use the format of your choice.

忘你却要生生世世 2024-08-31 16:21:11

如果您碰巧正在使用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': '[email protected]',
            'password': 'nancypassword',
            'staff': True,
            'superuser': True
        },
        {
            'username': 'joe',
            'email': '',
            'password': 'joepassword',
            'staff': True,
            'superuser': False
        },
        {
            'username': 'susan',
            'email': '[email protected]',
            '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()

然后只需运行迁移即可插入身份验证用户。

$ python manage.py migrate <some app name>

If you happen to be doing database migrations with south, creating users is very simple.

First, create a bare data migration. It needs to be included in some application. If you have a common app where you place shared code, that would be a good choice. If you have an app where you concentrate user-related code, that would be even better.

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

The pertinent migration code might look something like this:

# 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': '[email protected]',
            'password': 'nancypassword',
            'staff': True,
            'superuser': True
        },
        {
            'username': 'joe',
            'email': '',
            'password': 'joepassword',
            'staff': True,
            'superuser': False
        },
        {
            'username': 'susan',
            'email': '[email protected]',
            '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()

Then simply run the migration and the auth users should be inserted.

$ python manage.py migrate <some app name>
若相惜即相离 2024-08-31 16:21:11

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

另一种选择是覆盖syncdb命令并以您认为合适的方式应用固定装置。

我同意 Felix 的观点,Django 中不存在用于使用 SQL 填充 contrib 应用程序的重要自然钩子。

An option is to import your auth.User SQL manually and subsequently dump it out to a standard Django fixture (name it initial_data if you want syncdb to find it). You can generally put this file into any app's fixtures dir since the fixtured data will all be keyed with the proper app_label. Or you can create an empty/dummy app and place it there.

Another option is to override the syncdb command and apply the fixture in a manner as you see fit.

I concur with Felix that there is no non-trivial natural hook in Django for populating contrib apps with SQL.

┊风居住的梦幻卍 2024-08-31 16:21:11

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

I simply added SQL statements into the custom sql file for another model. I chose my Employee model because it depends on auth_user.
The custom SQL I wrote actually reads from my legacy application and pulls user info from it, and uses REPLACE rather than INSERT (I'm using MySQL) so I can run it whenever I want.
And I put that REPLACE...SELECT statement in a procedure so that it's easy to run manually or scheduled with cron.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文