Как загрузить светильник sql в Django для модели User? - PullRequest
13 голосов
/ 09 марта 2010

Кто-нибудь знает, как загрузить исходные данные для auth.User, используя sql fixtures? Для моих моделей у меня просто есть файл .sql в папке с именем sql, который syncdb прекрасно выполняет свою работу Но я понятия не имею, как это сделать для модели auth.User. Я гуглил, но безуспешно.

Заранее спасибо,

Aldo

Ответы [ 7 ]

24 голосов
/ 23 февраля 2011

Для фикстур SQL вам необходимо специально иметь операторы вставки для таблиц auth. Вы можете найти схему таблиц аутентификации с помощью команды python manage.py sql auth.

Гораздо более простой и независимый от базы данных способ (если у вас нет какой-то дополнительной магии SQL, которую вы хотите запустить) - просто создать файл JSON или YAML fixture в каталоге fixtures вашего приложения с данными как это:

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

Вы можете быстро создать хешированный пароль в оболочке django

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

Это будет загружаться при каждом запуске syncdb.

8 голосов
/ 09 марта 2010

Вы ищете loaddata:

manage.py loadata path/to/your/fixtureFile

Но я думаю, что команда может работать только с файлами в формате XML, YAML, Python или JSON ( см. Здесь ). Чтобы создать такие подходящие файлы, взгляните на метод dumpdata.

4 голосов
/ 30 сентября 2011

Для этого есть хитрость: (проверено на 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

В следующий раз, когда вы запустите python manage.py syncdb, Django автоматически загрузит аутентификационный прибор.

Пояснение:

  1. Просто создайте пустое приложение для хранения папки с приборами. Оставьте __init__py, models.py и views.py в нем, чтобы Django распознал его как приложение, а не просто как папку.
  2. Создайте папку с приложениями в приложении.
  3. python manage.py dumpdata auth сбросит данные «auth» в БД со всей информацией о группах и пользователях. Оставшаяся часть команды просто перенаправляет вывод в файл с именем initial_data.json, который ищет Django при запуске syncdb.
  4. Просто включите auth_fix в INSTALLED_APPS внутри settings.py.

В этом примере показано, как это сделать в JSON, но вы можете в основном использовать формат по вашему выбору.

4 голосов
/ 10 марта 2010

Спасибо за ваши ответы. Я нашел решение, которое работает для меня, и по совпадению было одним из предложений Брайана. Вот оно:

Вначале я отключил сигнал, который создал Super User после 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:

/ / 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. Временное решение этой проблемы - использовать INSERT IGNORE INTO в моей команде sql.

Я знаю, что это решение далеко от совершенства, и критики / улучшения / мнения приветствуются!

С уважением,

Aldo

3 голосов
/ 06 ноября 2011

Если вам приходится выполнять миграцию базы данных с юга, создание пользователей очень просто.

Сначала создайте чистую миграцию данных. Это должно быть включено в какое-то приложение. Если у вас есть общее приложение, в котором вы размещаете общий код, это будет хорошим выбором. Если у вас есть приложение, в котором вы концентрируете пользовательский код, это было бы еще лучше.

$ 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()

Затем просто запустите миграцию, и авторизованные пользователи должны быть вставлены.

$ python manage.py migrate <some app name>
3 голосов
/ 10 марта 2010

Опция заключается в том, чтобы импортировать ваш auth.User SQL вручную и затем выгрузить его в стандартное устройство Django (назовите его initial_data, если вы хотите, чтобы syncdb нашел его). Как правило, вы можете поместить этот файл в каталог приспособлений любого приложения, поскольку все фиксированные данные будут помечены соответствующим app_label. Или вы можете создать пустое / пустое приложение и поместить его туда.

Другой вариант - переопределить команду syncdb и применить прибор так, как вы считаете нужным.

Я согласен с Феликсом в том, что в Django нет нетривиального естественного хука для заполнения приложений contrib с помощью SQL.

1 голос
/ 10 апреля 2013

Я просто добавил операторы SQL в пользовательский файл sql для другой модели. Я выбрал модель Employee, потому что она зависит от auth_user. Пользовательский SQL, который я написал, фактически читает из моего старого приложения и извлекает из него информацию о пользователе и использует REPLACE, а не INSERT (я использую MySQL), поэтому я могу запускать его в любое время. И я поместил этот оператор REPLACE ... SELECT в процедуру, чтобы ее было легко запустить вручную или по расписанию с помощью cron.

...