仅使用Django的DB部分

时间:2009-02-23 21:45:55

标签: python django orm

有人知道Django是如何“模块化”的吗?我可以只使用ORM部分来获取映射到DB表的类,并知道如何从这些表中读/写吗?

如果没有,你会推荐什么作为“Hibernate的Python等价物”?

15 个答案:

答案 0 :(得分:89)

如果您喜欢Django的ORM,那么“独立”使用它非常简单;我written up several techniques for using parts of Django outside of a web context,您可以自由使用其中任何一种(或自己动手)。

上面的Shane似乎对此以及其他几点有点误导 - 例如,Django 可以执行多个不同的数据库,它只是默认对于那个(你需要在模型上做一个自定义管理器,使用除了“主”数据库以外的其他东西,这个东西并不太难,并且有一些食谱浮动它)。确实,Django本身并不进行连接管理/连接池,但我个人总是使用外部工具(例如,pgpool,这比任何内置于ORM的东西都要难得多)。

我建议花一些时间阅读,并可能尝试一些可能的谷歌搜索(例如,我链接到你的帖子作为“独立Django脚本”的最佳结果),以了解实际的内容最适合你的需求和口味 - 可能是Django的ORM不适合你,你不应该使用它,如果不是,但不幸的是那里有很多错误信息,这些都是混乱的水域。

编辑以响应谢恩:

同样,你似乎被误导了:SQLAlchemy需要配置(即告诉使用什么数据库,如何连接等),然后才能用它运行查询,那么Django需要类似配置的事实是怎样的(通过你选择的方法完成 - 你需要有一个完整的Django设置文件)任何劣势?

对于多个数据库支持,您似乎感到困惑:支持位于较低级别。查询对象 - 不是QuerySet,而是它将执行的基础Query对象知道它连接到哪个DB,并接受DB连接作为其初始化参数之一。告诉一个模型使用一个DB而另一个模型使用另一个模型就像在管理器上设置一个方法一样简单,该方法将正确的连接信息传递到Query。确实,没有更高级别的API,但这与“不支持”不同,与“需要自定义代码”不同(除非您认为在SQLAlchemy中显式配置多个DB,如果您需要多个,则需要DB,也是“自定义代码”)。

至于你是否使用django.db以外的东西间接结束,那么,是什么?事实上,django.db导入了比例django.utils,因为存在数据结构和其他代码,这些代码对于ORM而言非常有用,这在我个人关注的范围内是可以的;如果某些内容具有外部依赖关系或者使用标准Python库而不是100%自包含,那么一个人可能会抱怨。

答案 1 :(得分:12)

简短的回答是:不,你不能将Django ORM与Django分开使用。

答案很长:是的,如果你愿意加载Django的大部分内容,你可以。例如,当发出对Django的请求时,将打开Django使用的数据库连接。当发送信号时会发生这种情况,因此您可以在不使用特定请求机制的情况下表面上发送此信号以打开连接。此外,您需要为Django项目设置各种应用程序和设置。

最终,它可能不值得你花时间。 SQL Alchemy是一个比较着名的Python ORM,它实际上比Django更强大,因为它支持多个数据库连接和连接池以及其他好东西。


编辑:为了回应詹姆斯在其他地方的批评,我将澄清我在原帖中描述的内容。虽然令人欣慰的是Django的主要贡献者已经打电话给我,但我仍然认为我是对的:)

首先,考虑将Django的ORM与其他任何部分分开使用需要做些什么。您使用James描述的methods之一来进行Django的基本设置。但是许多这些方法不允许使用syncdb命令,这是为模型创建表所必需的。这需要一个settings.py文件,变量不仅适用于DATABASE_*,还需要INSTALLED_APPLICATIONS以及所有models.py文件的正确路径。

可以在没有settings.py的情况下推出自己的解决方案以使用syncdb,但它需要一些Django的高级知识。当然,您不需要使用syncdb;表格可以独立于模型创建。但是除非你付出一些努力进行设置,否则它是ORM的一个方面。

其次,考虑如何使用标准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解决方案,专为图书馆使用而设计。 Django不是。

不要以为所有上述表明我都不喜欢Django及其所有工作,我真的很喜欢Django!但我对它的功能是什么是现实的,并且成为一个ORM库不是其中之一。

P.S。正在worked上启用多个数据库连接支持。但它现在不存在了。

答案 2 :(得分:10)

(我正在报告我的解决方案,因为我的问题是重复的)

好吧我确定了,并且会为试图做同样事情的人发布解决方案。

此解决方案假定您要创建新模型。

首先创建一个新文件夹来存储您的文件。我们称之为“独立”。在“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目录。好的,你现在应该有以下结构:

\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

答案 3 :(得分:9)

你当然可以以独立的方式使用Django的各个部分。它只是一个Python模块的集合,您可以将其导入到您想要使用它们的任何其他代码。

如果您只是在ORM方面,我还建议您查看SQL Alchemy

答案 4 :(得分: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的{​​{1}}文件夹。为简单起见,配置使用sqlite,但它可以使用任何db后端。

文件夹结构:

models.py

请注意,您无需使用manage.py。 ./launcher.py ./modelsapp __init__.py models.py 只是找到它。

答案 5 :(得分:4)

我建议SQLAlchemy。它应该做所有ORM的东西,以及基本的SQL东西。

答案 6 :(得分:2)

看看django-standalone,这使得这个设置非常简单。

我还发现this blog entry非常有用。

答案 7 :(得分:2)

这个例子很简单。我已经有一个名为thab up and running的django应用程序。我想在自由站立的python脚本中使用django orm,并使用与我用于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

答案 8 :(得分:1)

我的答案可能已经很晚了,但迟到总比没有好。

试试这个简单的包: 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)

答案 9 :(得分:1)

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 version gte 1.8.x工作

答案 10 :(得分:1)

这对我来说很有用 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()

然后在python脚本中导入 conf.py

这是项目结构:

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

答案 11 :(得分:1)

使用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

答案 12 :(得分:1)

我知道这篇文章很旧,但是近年来,我发现一个较小的解决方案非常有用:

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附加以确保解析模块。

希望有帮助。

答案 13 :(得分:0)

  

我是否可以只使用ORM部分来获取映射到数据库表的类,并知道如何从这些表中读/写?

是的,你可以。

以下是关于如何使用Django的模型和数据库抽象的简洁简短解释:https://stackoverflow.com/a/49515366/2682613

Django版本: 2.0.2

答案 14 :(得分:0)

您可以在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_ZONEDatetimeFieldDateField与之相关。 最简单的设置应该是:

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

3。 close_old_connections

Django框架默认在每个请求中间件中运行close_old_connections以避免" mysql has gone away"。

PS :我已经编写了使用django orm的软件包,而不是经典的django项目https://github.com/jdxin0/django_db(https://github.com/jdxin0/django_db)。 但是你应该始终注意上面的三个问题。我的包使用元类来解决多个数据库,设置TIME_ZONE=None并将close_old_connections留给用户。