web-dev-qa-db-ja.com

DjangoのDB部分のみを使用する

誰かがDjangoが「モジュラー」であることを知っていますか? ORM部分だけを使用して、DBテーブルにマップするクラスを取得し、これらのテーブルから読み書きする方法を知ることはできますか?

そうでない場合、「Python Hibernateと同等)」として何を推奨しますか?

43
M. Elkstein

簡単に言えば、いいえ、Django ORMをDjangoと別に使用することはできません。

長い答えは:はい、それと一緒にDjangoの大部分をロードすることをいとわないのであれば、可能です。たとえば、Djangoへのリクエストが発生すると、Djangoが使用するデータベース接続が開かれます。これは、信号が送信されたときに発生し、特定の要求メカニズムを使用せずにこの信号を送信して接続を開くことができます。また、Djangoプロジェクトのさまざまなアプリケーションと設定をセットアップする必要があります。

結局、それはおそらくあなたの時間の価値はありません。 SQL Alchemy は比較的よく知られているPython ORMであり、複数のデータベース接続や接続プールなどの優れた機能をサポートしているため、Djangoのそれよりも実際に強力です。


編集:他の場所でのジェームズの批判に応えて、私は元の投稿で私が説明したことを明確にします。メジャーなDjango寄稿者から電話がかかってきたのは嬉しいことですが、それでも私は正しいと思います:)

まず、DjangoのORMを他の部分とは別に使用するために何が必要かを検討します。 Djangoの基本的なセットアップを行うために、Jamesが説明した methods の1つを使用します。ただし、これらのメソッドの多くは、モデルのテーブルを作成するために必要なsyncdbコマンドを使用できません。これには、settings.pyファイルが必要です。変数には、_DATABASE_*_だけでなく、すべてのmodels.pyファイルへの正しいパスを含む_INSTALLED_APPLICATIONS_も含まれます。

独自のソリューションをロールして、settings.pyなしでsyncdbを使用することは可能ですが、Djangoに関する高度な知識が必要です。もちろん、syncdbを使用する必要はありません。テーブルはモデルとは独立して作成できます。しかし、それはORMの1つの側面であり、セットアップに少し力を入れないと利用できません。

次に、標準のModel.objects.filter()呼び出しを使用してDBへのクエリを作成する方法を検討します。これがビューの一部として行われる場合、それは非常に簡単です。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の接続管理システムは tutorials などに記載されています。

最後に、データベース接続オブジェクトは常に現在のスレッドに対してローカルであり、要件に応じて制限される場合とされない場合があることに注意してください。アプリケーションがDjangoのようにステートレスではないが永続的である場合、スレッドの問題が発生する可能性があります。

結論として、それは意見の問題です。私の意見では、DjangoのORMの制限とフレームワークから分離されたORMの両方は、責任が大きすぎます。ライブラリの使用を目的として設計された、他に利用可能な完全に実行可能な専用ORMソリューションがあります。 Djangoはそうではありません。

上記のすべてが私がDjangoを嫌うことを示しているとは思わないでください、そしてそれはすべての働きです、私は本当にDjangoをとても好きです!しかし、私はそれが何であるかについて現実的であり、ORMライブラリであることはそれらの1つではありません。

追伸複数のデータベース接続がサポートされています 有効 オン。しかし、現在はありません。

13
Shane Breatnach

DjangoのORMが気に入ったら、「スタンドアロン」で使用するのは完全に簡単です。 Django Webコンテキストの外で一部を使用するためのいくつかのテクニックを書きました 、あなたはそれらのどれでも自由に使用できます(またはあなた自身をロールバックします)。

上記のシェーンは、これと他のいくつかの点について少し誤った情報を持っているようです-たとえば、Djangocan複数の異なるデータベースを実行できます)これにdefaultしません(「メイン」DB以外のものを使用するモデルでカスタムマネージャーを実行する必要があります。これはそれほど難しくなく、フローティングレシピがあります。 Django自体は接続管理/接続プーリングを行わないことは事実ですが、個人的にはとにかく、そのために常に外部ツールを使用してきました(例:pgpool 、これはORMに組み込まれたものよりもはるかに困難です)。

いくつかの時間をかけて読んで、おそらくいくつかのGoogle検索を試してみることをお勧めします(たとえば、「スタンドアローンDjango script ")のトップ結果として、リンクした投稿が表示されます。 DjangoのORMは適切ではないかもしれません。適切でない場合は使用しないでください。残念ながら、泥だらけの誤解がたくさんあります。水。

シェーンに返信するための編集:

繰り返しますが、誤解されているようです。SQLAlchemyを使用してクエリを実行する前に、SQLAlchemyを設定する必要があります(つまり、使用するDBや接続方法などを指示する必要があります)。したがって、Djangoは同様の設定が必要です(選択した方法で行います-あなたしないでください完全なDjango =設定ファイル)不利な点はありますか?

複数のDBサポートについては、混乱しているようです。サポートは低レベルにあります。クエリオブジェクト-QuerySetではなく、実行する基になるQueryオブジェクトは、接続先のDBを認識しており、初期化引数の1つとしてDB接続を受け入れます。あるモデルに1つのDBを使用するように指示し、別のモデルに別のDBを使用するよう指示するのは、正しい接続情報をQueryに渡すマネージャーで1つのメソッドを設定するのと同じくらい簡単です。確かに、これには上位レベルのAPIはありませんが、これは「サポートなし」とは異なり、「カスタムコードが必要」とは異なります(SQLAlchemyで複数のDBを明示的に構成すると主張しない限り、複数必要な場合DBも「カスタムコード」です)。

最終的に間接的にDjango.dbにないものを使用するかどうかについては、そうですか? Django.dbが、たとえばDjango.utilsのビットをインポートするという事実は、ORM以外にも役立つデータ構造やその他のコードのビットがあるため、個人的には問題ありません。 100%自己完結型ではなく、外部依存関係があるか、標準のPythonライブラリを使用している場合、不平を言うかもしれません。

91
James Bennett

(私の質問は重複していると言われたので、私の解決策を報告しています)

ああ、わかりました。同じことをやろうとしている人のための解決策を投稿します。

このソリューションでは、新しいモデルを作成することを想定しています。

まず、ファイルを保存する新しいフォルダーを作成します。これを「standAlone」と呼びます。 「standAlone」内で、次のファイルを作成します。

__init__.py
myScript.py
settings.py

明らかに、「myScript.py」の名前は何でもかまいません。

次に、モデルのディレクトリを作成します。

モデルディレクトリには「myApp」という名前を付けますが、これはプロジェクト内の通常のDjangoアプリケーションであることを理解しているため、作成するモデルのコレクションに合わせて適切に名前を付けてください。

このディレクトリ内に2つのファイルを作成します。

__init__.py
models.py

既存のDjangoプロジェクトからのmanage.pyのコピーが必要になるか、または単にDjangoインストールパスからコピーを取得できます。

Django\conf\project_template\manage.py

Manage.pyを/ standAloneディレクトリにコピーします。 Okこれで、次の構造になるはずです。

\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データベースを管理するには、コマンドプロンプトで/ standaloneディレクトリに移動し、次のコマンドを実行します。

manage.py sql MyApp
10

確かにDjangoのさまざまな部分をスタンドアロンで使用できます。結局のところ、これはPythonモジュールのコレクションにすぎません。それらを使用したい他のコード。

SQL Alchemy を見て、ORM側だけに目を向けることもお勧めします。

9
Andy Hume

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__.pymodels.py。設定は、単純化のためにsqliteを使用していますが、dbバックエンドのいずれを使用することもできます。

フォルダー構造:

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

適切なmanage.pyを持っている必要はないことに注意してください。 import execute_from_command_lineはそれを見つけます。

5
RobotHumans

Django 2.0 ORM-1つのファイルが必要

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
5
Scott P.

SQLAlchemy をお勧めします。 ORMに関するすべての処理と、基本的なSQLに関する処理を実行する必要があります。

4
dwc

この例は非常に簡単です。すでにDjangoアプリがthab up and runningと呼ばれています。Django独立したormを使用したいpythonスクリプトと、私がWebプログラミングで使用しているのと同じモデルを使用します。以下に例を示します。

# 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
2
Jim Paul

この設定をかなり簡単にする Django-standalone を見てください。

このブログエントリ も非常に役に立ちました。

2
Ber

ORM部分だけを使用して、DBテーブルにマップするクラスを取得し、これらのテーブルから読み書きする方法を知ることはできますか?

はい、できます。

Djangoのモデルとデータベースの抽象化の使用方法に関する簡潔でshortの説明を次に示します。 https:// stackoverflow。 com/a/49515366/268261

Djangoバージョン:2.0.2

1
IvanJijon
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

1
Pengfei.X

おそらく私は私の答えにかなり遅れていますが、それは決して遅いよりはましです。

次のシンプルなパッケージを試してください: https://github.com/serglopatin/Django-models-standalone

使い方:

  1. ダウンロード

  2. インストール

    python setup.py install
    
  3. プロジェクトを作成する

    Django-models-standalone startproject myproject
    
  4. ファイルsettings.py(DATABASES)とmodels.pyを調整し、テーブルが作成されていない場合は移行します

  5. アプリケーションでdjandoモデルを使用する(example.py)

1
Sergey

これはDjango> 1.4で私のために働いたものです

スタンドアロンスクリプトがあなたのDjangoプロジェクトDIRであると仮定します。

これを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スクリプトにインポートします。

これはプロジェクト構造です:

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

私はこの投稿が古いことを理解していますが、近年、より小さな解決策がうまく機能することがわかりました:

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付加を適用してモジュールが解決されていることを確認します。

それが役に立てば幸い。

1
Glycerine

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_ZONEDatetimeFieldおよびDateFieldはそれに関連しています。最も簡単な設定は次のとおりです。

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

3. close_old_connections

Djangoフレームワークのデフォルトでは、すべてのリクエストミドルウェアでclose_old_connectionsを実行して、「 mysqlが廃止されました 」を回避します。


[〜#〜] ps [〜#〜]:使用するパッケージを記述しましたDjangoクラシックDjangoプロジェクト、 https://github.com/jdxin0/Django_db(https://github.com/jdxin0/Django_db) 。ただし、常に支払う必要があります上記の3つの問題に注意してください。私のパッケージはメタクラスを使用してマルチdbを解決し、TIME_ZONE=None そして去る close_old_connectionsユーザーに。

0
jdxin0