python - query - Usando solo la parte DB de Django
orm para django (14)
¿Puedo usar solo la parte ORM para obtener clases que se relacionen con las tablas DB y sepa leer / escribir en estas tablas?
Sí tu puedes.
Aquí hay una explicación breve y clara sobre cómo usar los modelos de Django y la abstracción de la base de datos : https://stackoverflow.com/a/49515366/2682613
Versión de Django: 2.0.2
¿Alguien sabe qué tan "modular" es Django? ¿Puedo usar solo la parte ORM para obtener clases que se relacionen con las tablas DB y sepa leer / escribir en estas tablas?
Si no, ¿qué recomendarías como "el equivalente Python de Hibernate"?
Usando Django 2.0 ORM - Se requiere un archivo
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
(Estoy informando mi solución porque mi pregunta dice que es un duplicado)
Ah ok, lo descubrí y publicaré las soluciones para cualquiera que intente hacer lo mismo.
Esta solución asume que desea crear nuevos modelos.
Primero crea una nueva carpeta para almacenar tus archivos. Lo llamaremos "standAlone". Dentro de "standAlone", crea los siguientes archivos:
__init__.py
myScript.py
settings.py
Obviamente, "myScript.py" puede denominarse lo que sea.
A continuación, crea un directorio para tus modelos.
Nombraremos nuestro directorio de modelos "myApp", pero nos daremos cuenta de que esta es una aplicación Django normal dentro de un proyecto, por lo tanto, asígnele un nombre apropiado a la colección de modelos que está escribiendo.
Dentro de este directorio crea 2 archivos:
__init__.py
models.py
Necesitará una copia de manage.py de un proyecto existente de Django o puede obtener una copia de la ruta de instalación de Django:
django/conf/project_template/manage.py
Copie el manage.py en su directorio / standAlone. Bien, ahora deberías tener la siguiente estructura:
/standAlone
__init__.py
myScript.py
manage.py
settings.py
/myApp
__init__.py
models.py
Agregue lo siguiente a su archivo 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 *
y agregue esto a su archivo settings.py:
DATABASE_ENGINE = "postgresql_psycopg2"
DATABASE_NAME = "myDatabase"
DATABASE_USER = "myUsername"
DATABASE_PASSWORD = "myPassword"
DATABASE_HOST = "localhost"
DATABASE_PORT = "5432",
INSTALLED_APPS = ("myApp")
y finalmente tu myApp / models.py:
# myApp/models.py
from django.db import models
class MyModel(models.Model):
field = models.CharField(max_length=255)
y eso es. Ahora para que Django administre su base de datos, en el símbolo del sistema navegue a nuestro directorio / independiente y ejecute:
manage.py sql MyApp
Echa un vistazo a django-standalone que hace que esta configuración sea bastante fácil.
También encontré esta entrada en el blog bastante útil.
Este ejemplo es tan simple como se pone. Ya tengo una aplicación django llamada thab en funcionamiento. Quiero usar django orm en scripts de python autónomos y usar los mismos modelos que estoy usando para la programación web. Aquí hay un ejemplo:
# 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
Esto es lo que funcionó para mí en Django> 1.4
Asumiendo que su script independiente es su proyecto django DIR.
Solo copie esto en un archivo conf.py (puede darle cualquier nombre).
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()
Luego importe el conf.py en su script python.
Esta es la estructura del proyecto:
mydjangoproject
|
> app1
> core
> app2
> standalone
| | __init__.py
| | conf.py
| | myscript.py
> manage.py
Estoy usando django ORM sin un archivo de configuración. Así es cómo:
En el archivo del iniciador de aplicaciones autónomo:
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)
Ahora solo necesita una carpeta ./modelsapp
contenga un __init__.py
y un models.py
. La configuración usa sqlite por simplicidad, pero podría usar cualquiera de los servidores de fondo db.
Estructura de la carpeta:
./launcher.py
./modelsapp
__init__.py
models.py
Tenga en cuenta que no necesita tener un manage.py adecuado. La import execute_from_command_line
solo lo encuentra.
La respuesta corta es: no, no puede usar el ORM de Django por separado de Django.
La respuesta larga es: sí, puedes si estás dispuesto a cargar partes grandes de Django junto con ella. Por ejemplo, la conexión de la base de datos que utiliza Django se abre cuando se produce una solicitud a Django. Esto sucede cuando se envía una señal, por lo que es posible que envíe esta señal para abrir la conexión sin utilizar el mecanismo de solicitud específico. Además, necesitaría configurar las diversas aplicaciones y configuraciones para el proyecto Django.
En última instancia, probablemente no valga la pena su tiempo. SQL Alchemy es un ORM de Python relativamente bien conocido, que en realidad es más poderoso que el de Django, ya que admite múltiples conexiones de bases de datos y agrupación de conexiones y otras cosas buenas.
Editar: en respuesta a las críticas de James en otros lugares, aclararé lo que describí en mi publicación original. Si bien es gratificante que un colaborador importante de Django me haya llamado, todavía creo que estoy en lo cierto :)
Primero, considere lo que se debe hacer para usar el ORM de Django separado de cualquier otra parte. Utiliza uno de los methods descritos por James para hacer una configuración básica de Django. Pero varios de estos métodos no permiten el uso del comando syncdb
, que es necesario para crear las tablas para sus modelos. Se necesita un archivo settings.py para esto, con variables no solo para DATABASE_*
, sino también INSTALLED_APPLICATIONS
con las rutas correctas a todos los archivos models.py.
Es posible rodar su propia solución para usar syncdb
sin un settings.py, pero requiere un conocimiento avanzado de Django. Por supuesto, no necesita usar syncdb
; las tablas se pueden crear independientemente de los modelos. Pero es un aspecto del ORM que no está disponible a menos que ponga un poco de esfuerzo en la configuración.
En segundo lugar, considere cómo crearía sus consultas al DB con la Model.objects.filter()
estándar Model.objects.filter()
. Si esto se hace como parte de una vista, es muy simple: construir el QuerySet
y ver las instancias. Por ejemplo:
tag_query = Tag.objects.filter( name='''' )
if( tag_query.count() > 0 ):
tag = tag_query[0]
tag.name = ''ed''
tag.save()
Agradable, simple y limpio. Ahora, sin la muleta del sistema de encadenamiento de solicitud / respuesta de Django, debe inicializar la conexión de la base de datos, realizar la consulta y luego cerrar la conexión. Entonces el ejemplo de arriba se convierte en:
from django.db import reset_queries, close_connection, _rollback_on_exception
reset_queries()
try:
tag_query = Tag.objects.filter( name='''' )
if( tag_query.count() > 0 ):
tag = tag_query[0]
tag.name = ''ed''
tag.save()
except:
_rollback_on_exception()
finally:
close_connection()
La gestión de la conexión de la base de datos también se puede realizar a través de señales de Django. Todo lo anterior se define en django/db/init.py . Otros ORM también tienen este tipo de gestión de conexión, pero no necesita profundizar en su fuente para averiguar cómo hacerlo. El sistema de administración de conexiones de SQL Alchemy está documentado en los tutorials y en otros lugares.
Finalmente, debe tener en cuenta que el objeto de conexión de la base de datos es local al hilo actual en todo momento, lo que puede o no limitarlo según sus requisitos. Si su aplicación no es apátrida, como Django, sino persistente, puede llegar a problemas de enhebrado.
En conclusión, es una cuestión de opinión. En mi opinión, tanto las limitaciones como la configuración necesarias para el ORM de Django, separado del marco, son demasiadas responsabilidades. Hay soluciones de ORM dedicadas perfectamente viables disponibles en otros lugares que están diseñadas para el uso de la biblioteca. Django no es.
No creas que todo lo anterior muestra que no me gusta Django y todo lo que funciona, ¡realmente me gusta mucho Django! Pero soy realista sobre cuáles son sus capacidades y ser una biblioteca ORM no es una de ellas.
PS Se está worked en la compatibilidad con la conexión a múltiples bases de datos. Pero no está allí ahora.
Probablemente llegué bastante tarde con mi respuesta, pero es mejor tarde que nunca.
Pruebe este paquete simple: https://github.com/serglopatin/django-models-standalone
Cómo utilizar:
descargar
instalar
python setup.py install
crear proyecto
django-models-standalone startproject myproject
ajuste los archivos settings.py (DATABASES) y models.py, luego migre si no se crean tablas
use modelos de djando en su aplicación (ejemplo.py)
Puedes usarlo fuera de un proyecto django. Pero hay cosas que debes tener en cuenta.
1. Enrutador de base de datos múltiple.
Un enrutador se ve así:
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
Puede usar metaclase para crear un enrutador dinámico.
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. Configuraciones de Django.
la clave más importante es TIME_ZONE
. DatetimeField
y DateField
se lo relacionan. Una configuración más simple debería ser:
SECRET_KEY = ''secret''
DATABASES = {''default'': {}}
DATABASE_ROUTERS = []
TIME_ZONE = None
3. close_old_connections
.
Django framework ejecuta por defecto close_old_connections en cada middleware de solicitud para evitar que " mysql se haya ido ".
PD : He escrito el paquete para usar django orm no en un proyecto django clásico, https://github.com/jdxin0/django_db(https://github.com/jdxin0/django_db) . Pero siempre debe prestar atención a los tres problemas anteriores. Mi paquete usa metaclase para resolver múltiples db, establecer TIME_ZONE=None
y dejar close_old_connections
al usuario.
Recomiendo SQLAlchemy . Debería hacer todas las cosas de ORM, así como las cosas básicas de SQL.
Si te gusta el ORM de Django, es perfectamente sencillo usarlo como "independiente"; He methods , y puedes usar cualquiera de ellas (o puedes usar las tuyas propias).
Shane arriba parece estar un poco mal informado sobre este y algunos otros puntos; por ejemplo, Django puede hacer múltiples bases de datos diferentes, simplemente no se trata de eso (necesitas hacer un administrador personalizado en los modelos que usan algo diferente). que la base de datos "principal", algo que no es demasiado difícil y hay recetas flotando para ello). Es cierto que Django no hace la gestión de conexión / agrupación de conexiones, pero personalmente siempre he usado herramientas externas para eso ( pgpool
, que oscila más duro que cualquier cosa integrada en un ORM).
Sugeriría pasar algo de tiempo leyendo y posiblemente probando algunas posibles búsquedas de Google (por ejemplo, la publicación a la que te he vinculado aparece como el resultado principal de "script independiente de Django") para tener una idea de qué es lo que realmente mejor se adapta a tu necesidades y gustos: puede ser que el ORM de Django no sea el adecuado para usted, y no debe usarlo si no lo es, pero desafortunadamente hay mucha información errónea que enloda las aguas.
Editando para responder a Shane:
Nuevamente, parece que está mal informado: SQLAlchemy necesita configuración (es decir, qué DB usar, cómo conectarse, etc.) antes de poder ejecutar consultas con él, entonces, ¿cómo es que Django necesita una configuración similar (realizada a través de su elección de métodos, no es necesario tener un archivo de configuración completo de Django, ¿tiene alguna desventaja?
En cuanto al soporte de múltiples DB, pareces estar confundido: el soporte está ahí en un nivel bajo. El objeto de consulta, no QuerySet
, pero el objeto Query
subyacente que ejecutará sabe a qué DB se está conectando, y acepta una conexión DB como uno de sus argumentos de inicialización. Decir a un modelo que use un DB y otro modelo para usar otro es tan simple como configurar un método en un administrador que transfiera la información de conexión correcta a la Query
. Es cierto que no hay una API de nivel superior para esto, pero eso no es lo mismo que "sin soporte" y no es lo mismo que "requiere código personalizado" (a menos que discuta que configurar varias bases de datos de forma explícita en SQLAlchemy, necesario si lo desea) DBs, también es "código personalizado").
En cuanto a si terminas usando indirectamente cosas que no están en django.db
, ¿y qué? El hecho de que django.db
importe bits de, digamos, django.utils
porque hay estructuras de datos y otros bits de código que son útiles para algo más que un ORM está bien en lo que a mí concierne personalmente; uno también podría quejarse si algo tiene dependencias externas o hace uso de bibliotecas estándar de Python en lugar de ser 100% autónomo.
Sin duda, puedes usar varias partes de Django de manera independiente. Después de todo, es solo una colección de módulos de Python, que puede importar a cualquier otro código que quiera usar.
También te recomendaría buscar SQL Alchemy si solo buscas el lado ORM de las cosas.
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()
mira esto, está funcionando para django versión gte 1.8.x