Использование только части DB Django

Кто-нибудь знает, насколько "модульным" является Django? Могу ли я использовать только часть ORM, чтобы получить классы, которые сопоставляются с таблицами БД и умеют читать/записывать из этих таблиц?

Если нет, что бы вы рекомендовали как "эквивалент Python Hibernate"?

Ответ 1

Короткий ответ: no, вы не можете использовать Django ORM отдельно от Django.

Долгий ответ: да, вы можете, если захотите загрузить большие части Django вместе с ним. Например, соединение с базой данных, которое используется Django, открывается при возникновении запроса на Django. Это происходит, когда сигнал отправляется, чтобы вы могли якобы отправить этот сигнал, чтобы открыть соединение, не используя механизм запроса. Кроме того, вам необходимо настроить различные приложения и настройки для проекта Django.

В конечном счете, это, вероятно, не стоит вашего времени. SQL Alchemy - относительно хорошо известный Python ORM, который на самом деле более мощный, чем Django, так как он поддерживает несколько подключений к базе данных и пул соединений и другие хорошие вещи.


Изменить: в ответ на критику Джеймса в другом месте, я уточню, что я описал в своем оригинальном посте. Хотя приятно, что главный участник Django вызвал меня, я все еще думаю, что я прав:)

Прежде всего, рассмотрите, что нужно сделать, чтобы использовать Django ORM отдельно от любой другой части. Вы используете один из методов , описанных Джеймсом для выполнения базовой настройки Django. Но многие из этих методов не позволяют использовать команду syncdb, которая требуется для создания таблиц для ваших моделей. Для этого необходим файл settings.py, с переменными не только для DATABASE_*, но также INSTALLED_APPLICATIONS с правильными путями ко всем файлам models.py.

Можно использовать собственное решение для использования syncdb без settings.py, но для этого требуется некоторое расширенное знание Django. Конечно, вам не нужно использовать syncdb; таблицы могут быть созданы независимо от моделей. Но это аспект ORM, который недоступен, если вы не приложите некоторые усилия к настройке.

Во-вторых, рассмотрите, как вы создадите свои запросы в БД стандартным вызовом Model.objects.filter(). Если это делается как часть представления, это очень просто: постройте QuerySet и просмотрите экземпляры. Например:

tag_query = Tag.objects.filter( name='stackoverflow' )
if( tag_query.count() > 0 ):
    tag = tag_query[0]
    tag.name = 'stackoverflowed'
    tag.save()

Приятный, простой и чистый. Теперь, без костыли системы запроса/ответа Django, вам нужно инициализировать соединение с базой данных, выполнить запрос, а затем закрыть соединение. Таким образом, приведенный выше пример выглядит следующим образом:

from django.db import reset_queries, close_connection, _rollback_on_exception
reset_queries()
try:
    tag_query = Tag.objects.filter( name='stackoverflow' )
    if( tag_query.count() > 0 ):
        tag = tag_query[0]
        tag.name = 'stackoverflowed'
        tag.save()
except:
    _rollback_on_exception()
finally:
    close_connection()

Управление подключением к базе данных также можно выполнить с помощью сигналов Django. Все вышесказанное определено в django/db/ init.py. Другие ORM также имеют такое управление соединениями, но вам не нужно вникать в их источник, чтобы узнать, как это сделать. Система управления соединениями SQL Alchemy задокументирована в учебниках и в других местах.

Наконец, вам нужно иметь в виду, что объект подключения к базе данных является локальным для текущего потока во все времена, что может или не может ограничивать вас в зависимости от ваших требований. Если ваше приложение не является апатридом, например Django, но постоянно, вы можете столкнуться с проблемами с потоками.

В заключение, это вопрос мнения. На мой взгляд, и ограничения, и настройки, требуемые для Django ORM отдельно от структуры, являются слишком значительной частью ответственности. В любом месте существуют идеально доступные решения ORM, предназначенные для использования в библиотеке. Джанго - нет.

Не думайте, что все выше сказанное мне не нравится Django и все его работы, мне действительно нравится Django! Но я реалист о том, что это за возможности, и быть библиотекой ORM, не является одним из них.

P.S. Поддержка нескольких подключений к базе данных работала. Но теперь его нет.

Ответ 2

Если вам нравится Django ORM, совершенно просто использовать его "standalone"; Я написал несколько методов для использования частей Django вне веб-контекста, и вы можете использовать любой из них (или рулон ваш собственный).

Шейн выше, кажется, немного дезинформирован по этому поводу и нескольким другим моментам - например, Django может выполнять несколько разных баз данных, он просто не делает этого по умолчанию (вам нужно сделать собственный менеджер на моделях, которые используйте что-то другое, кроме "основной" БД, что-то, что не слишком сложно, и есть рецепты, плавающие вокруг). Это правда, что Django сам не выполняет управление подключением/пулом соединений, но лично я всегда использовал внешние инструменты для этого (например, pgpool, который превосходит все, что было в ORM).

Я предлагаю потратить некоторое время на чтение и, возможно, попробовать несколько возможных поисков Google (например, сообщение, которое я связал с вами, подходит к первому результату для "автономного Django script" ), чтобы понять, что на самом деле будет наилучшим образом удовлетворить ваши потребности и вкусы - возможно, Django ORM не подходит вам, и вы не должны использовать его, если это не так, но, к сожалению, там много дезинформации, которая загрязняет воды.

Редактирование для ответа на Shane:

Опять же, вы, кажется, дезинформированы: SQLAlchemy нужно настроить (то есть сказать, какой БД использовать, как подключиться и т.д.), прежде чем вы сможете запускать с ним запросы, так как же факт, что Django нуждается в подобной конфигурации (выполненный с помощью вашего выбора методов - вы не должны иметь полный файл настроек Django) любой недостаток?

Что касается поддержки нескольких БД, вы, похоже, путаетесь: поддержка существует на низком уровне. Объект запроса - не QuerySet, но базовый объект Query, который он выполнит, знает, к какому БД он подключается, и принимает соединение с БД как один из своих аргументов инициализации. Говорить одной модели с использованием одной БД и другой модели для использования другой так же просто, как настроить один метод на менеджере, который передает правильную информацию о подключении вниз в Query. Правда, для этого нет более высокого уровня API, но это не то же самое, что "нет поддержки", а не то же самое, что "требуется специальный код" (если вы не будете утверждать, что настройка нескольких БД явно в SQLAlchemy требуется, если вы хотите, чтобы несколько DB, также является "настраиваемым кодом" ).

Что касается того, косвенно ли вы используете вещи, которые не находятся в django.db, ну и что? Тот факт, что django.db импортирует биты, скажем, django.utils, потому что существуют структуры данных и другие биты кода, которые полезны не только для ORM, насколько я лично заинтересован; можно было бы жаловаться, если что-то имеет внешние зависимости или использует стандартные библиотеки Python вместо 100% автономного.

Ответ 3

(Я сообщаю свое решение, потому что мой вопрос считается дубликатом)

А, я понял, что опубликую решения для тех, кто пытается сделать то же самое.

Это решение предполагает, что вы хотите создавать новые модели.

Сначала создайте новую папку для хранения ваших файлов. Мы назовем его "standAlone". Внутри "standAlone" создайте следующие файлы:

__init__.py
myScript.py
settings.py

Очевидно, что "myScript.py" можно назвать любым.

Затем создайте каталог для своих моделей.

Мы назовем наш каталог моделей "myApp", но поймем, что это нормальное приложение Django в рамках проекта, как таковое, соответствующим образом назовите его для коллекции моделей, которые вы пишете.

В этом каталоге создайте 2 файла:

__init__.py
models.py

Вам понадобится копия manage.py из существующего проекта Django или вы можете просто взять копию с установочного пути Django:

django\conf\project_template\manage.py

Скопируйте файл manage.py в каталог /standAlone. Итак, теперь у вас должна быть следующая структура:

\standAlone
    __init__.py
    myScript.py
    manage.py
    settings.py
\myApp
    __init__.py
    models.py

Добавьте в файл myScript.py следующее:

# settings.py
from django.conf import settings

settings.configure(
    DATABASE_ENGINE    = "postgresql_psycopg2",
    DATABASE_NAME      = "myDatabase",
    DATABASE_USER      = "myUsername",
    DATABASE_PASSWORD  = "myPassword",
    DATABASE_HOST      = "localhost",
    DATABASE_PORT      = "5432",
    INSTALLED_APPS     = ("myApp")
)

from django.db import models
from myApp.models import *

и добавьте это в свой файл settings.py:

    DATABASE_ENGINE    = "postgresql_psycopg2"
    DATABASE_NAME      = "myDatabase"
    DATABASE_USER      = "myUsername"
    DATABASE_PASSWORD  = "myPassword"
    DATABASE_HOST      = "localhost"
    DATABASE_PORT      = "5432",
    INSTALLED_APPS     = ("myApp")

и, наконец, ваш myApp/models.py:

# myApp/models.py
from django.db import models

class MyModel(models.Model):
     field = models.CharField(max_length=255)

и что он. Теперь, чтобы Django управлял вашей базой данных, в командной строке перейдите в наш/автономный каталог и запустите:

manage.py sql MyApp

Ответ 4

Вы можете, конечно, использовать различные части Django в автономном режиме. Это всего лишь коллекция модулей Python, которую вы можете импортировать в любой другой код, который вы хотели бы использовать.

Я также рекомендую посмотреть SQL Alchemy, если вы только после ORM-стороны вещей.

Ответ 5

Я использую django ORM без файла настроек. Вот как:

В автономном файле запуска приложения:

from django.conf import settings
from django.core.management import execute_from_command_line

#Django settings
settings.configure(DEBUG=False,
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': '/path/to/dbfile',
            'USER': '',
            'PASSWORD': '',
            'HOST': '',
            'PORT': '',
        }
    },
    INSTALLED_APPS = ('modelsapp',)
)

if not os.path.exists('/path/to/dbfile'):
    sync = ['manage.py', 'syncdb']
    execute_from_command_line(sync)

Теперь вам нужна папка ./modelsapp, содержащая __init__.py и models.py. Конфигурация использует sqlite для простоты, но может использовать любой из бэкэндов db.

Структура папки:

./launcher.py
./modelsapp
    __init__.py
    models.py

Обратите внимание, что вам не обязательно иметь manage.py. import execute_from_command_line просто находит его.

Ответ 6

Я рекомендую SQLAlchemy. Он должен делать все вещи ORM, а также основные вещи SQL.

Ответ 8

Этот пример так же прост, как и он. У меня уже есть приложение django, называемое thab и работающее. Я хочу использовать django orm в свободно стоящих сценариях python и использовать те же модели, что и для веб-программирования. Вот пример:

# nothing in my sys.path contains my django project files
import sys
sys.path.append('c:\\apython\\thab')  # location of django app (module) called thab          where my settings.py and models.py is
# my settings.py file is actualy in c:\apython\thab\thab
from thab import settings as s  # need it because my database setting are there
dbs = s.DATABASES
from django.conf import settings
settings.configure(DATABASES=dbs) # configure can only be called once
from thab.models import *
boards = Board.objects.all()
print 'all boards:' + str(boards) # show all the boards in my board table

Ответ 9

Использование Django 2.0 ORM - требуется один файл

from myproject.config import parse_config
from django import setup as django_setup
from django.conf import settings as django_settings

"""
Requirements:
  ODBC Driver: https://www.microsoft.com/en-ca/download/details.aspx?id=36434
  Django Engine: https://pypi.org/project/django-pyodbc-azure/
"""

config = parse_config()
django_settings.configure(
    DEBUG=True,
    DATABASES={
        'default': {
            'ENGINE': 'sql_server.pyodbc',
            'NAME': config.database_name,
            'HOST': config.database_server,  # exclude '\\MSSQLSERVER'
            'USER': config.database_username,
            'PASSWORD': config.database_password,
            'PORT': '',
            'AUTOCOMMIT': False,
            'OPTIONS': {
                'driver': 'ODBC Driver 11 for SQL Server',
            },
        },
    })
django_setup()


from django.db import models

class Foo(models.Model):
    name = models.CharField(max_length=25)

    class Meta:
        app_label = 'myapp'  # each model will require this

Ответ 10

Возможно, я опоздал с ответом, но лучше поздно, чем никогда.

Попробуйте этот простой пакет: https://github.com/serglopatin/django-models-standalone

Как использовать:

  • скачать

  • установить

    python setup.py install
    
  • создать проект

    django-models-standalone startproject myproject
    
  • отрегулируйте файлы settings.py(DATABASES) и models.py, а затем перенесите, если таблицы не созданы

  • используйте модели djando в своем приложении (example.py)

Ответ 11

import django
from django.conf import settings
from backend_mock.admin import settings as s
settings.configure(
    DATABASES=s.DATABASES,
    INSTALLED_APPS=('backend_mock.admin.mocker', )
)
django.setup()

взгляните на это, он работает для версии django gte 1.8.x

Ответ 12

Это то, что сработало для меня в Django > 1.4

Предполагая, что ваш автономный script - это DIR-проект django.

Просто скопируйте это в файл conf.py (вы можете дать ему любое имя).

import os
import sys
import django

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR) 
#sys.path.append('c:\\apython\\thab')
 # location of django app (module) called thab          where my settings.py and models.py is
# my settings.py file is actualy in c:\apython\thab\thab
from elsaserver import settings as s  # need it because my database setting are there
dbs = s.DATABASES
from django.conf import settings
settings.configure(
    DATABASES=dbs,
    INSTALLED_APPS=('core.apps.CoreConfig', )) #add all the apps you need here
django.setup()

Затем импортируйте conf.py в свой python script.

Это структура проекта:

mydjangoproject
    |
    > app1
    > core
    > app2
    > standalone
    | | __init__.py  
    | | conf.py  
    | | myscript.py
    > manage.py

Ответ 13

  Могу ли я использовать только часть ORM, чтобы получить классы, которые сопоставляются с таблицами БД, и знать, как читать/писать из этих таблиц?

Да, вы можете.

Вот краткое и краткое объяснение того, как использовать модели Django и абстракцию базы данных: fooobar.com/questions/14170518/...

Версия Django: 2.0.2

Ответ 14

Я понимаю, что этот пост старый, но в последние годы я обнаружил, что меньшее решение прекрасно работает:

import os, sys
import django

# sys.path.append('/abs/path/to/my-project/)
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
django.setup()

# Use
from myapp import models
kv = models.KeyValue()

Обеспечение запуска этого сценария в соответствующем относительном каталоге или применение добавления sys PATH, чтобы убедиться, что модули разрешены.

Надеюсь, это поможет.

Ответ 15

Вы можете использовать его вне проекта django. Но есть вещи, о которых вы должны знать.

1. Маршрутизатор с несколькими базами данных.

Маршрутизатор выглядит так:

class Router(object):
    app_label = ''

    def db_for_read(self, model, **hints):
        if model._meta.app_label == self.app_label:
            return self.app_label
        return None

    def db_for_write(self, model, **hints):
        if model._meta.app_label == self.app_label:
            return self.app_label
        return None

    def allow_relation(self, obj1, obj2, **hints):
        if obj1._meta.app_label == self.app_label or obj2._meta.app_label == self.app_label:
           return True
        return None

    def allow_migrate(self, db, app_label, model=None, **hints):
        if app_label == self.app_label:
            return db == self.app_label
    return None

Вы можете использовать метакласс для динамического создания маршрутизатора.

def add_db(db_conf):
    app_label = 'al_' + str(uuid4())

    settings.DATABASES[app_label] = db_conf

    router_class_name = 'Router' + app_label.capitalize()
    setattr(
        settings,
        router_class_name,
        type(router_class_name, (Router,), dict(app_label=app_label)),
    )
    settings.DATABASE_ROUTERS.append(
        '.'.join([settings.__name__, router_class_name])
    )
    connections.close_all()
return app_label

2. Настройки Django.

самый важный ключ - TIME_ZONE. DatetimeField и DateField высвобождаются к нему. Самый простой параметр должен быть следующим:

SECRET_KEY = 'secret'
DATABASES = {'default': {}}
DATABASE_ROUTERS = []
TIME_ZONE = None

3. close_old_connections.

Платформа Django по умолчанию запускает close_old_connections в каждом промежуточном программном обеспечении запроса, чтобы избежать "mysql ушел".


PS: я написал пакет для использования django orm, а не в классическом проекте django, https://github.com/jdxin0/django_db(https://github.com/jdxin0/django_db). Но вы всегда должны обращать внимание на три вышеуказанные проблемы. Мой пакет использует метакласс для решения multi db, установите TIME_ZONE=None и оставьте close_old_connections пользователю.