2

I've enjoyed using Django quite a bit over the years. Right now I'm working for a company that is building some shared internal libraries for accessing information from our databases. Right now things are terribly sloppy - lots of inline SQL code. Some colleagues were working on doing some accessing code, and it occurred to me that this is the sort of thing that I'm used to Django doing out of the box. I had also heard that Django is fundamentally modular, so that I could just use the ORM system in isolation. I know there are other packages for this like SqlAlchemy, but I also hear that Django does things easier for the average case, which is likely all we'll need. I also know Django, and don't know SQLAlchemy.

So, I can do a proof of concept, like the following. Here is the directory structure:

+-- example.py
+-- transfer
|   +-- __init__.py
|   +-- models.py

Here is models.py

import django.conf
import django.db.models

django.conf.settings.configure(
    DATABASES = ..., # database info
    INSTALLED_APPS = ("transfer",),
    SECRET_KEY = 'not telling',
)
django.setup()

class TransferItem(django.db.models.Model)
    # model info here

example.py

from transfer.models import TransferItem
items = TransferItem.objects.all()
print items

This seems to work fine, as far as it goes. But I'm worried about the bootstrap code in a library context. Specifically:

  1. Is there danger in django thinking of this as an app? In this case, "transfer" is a root module, but in a library context this could be buried deep. For example, "mycompany.data.protocols.transfer". Theoretically, we could have these data models defined throughout the codebase. How can this "app list" scale?
  2. The call to setup really worries me. The django docs specifically say only to call setup once. And yet the nature of a library is that any python application could import whatever type of data model they want. I can't make any assumptions about which django "apps" they might want, or what order they want it in. Would if one type of model is used, data is returned, and only then does the python application decide it needs to import another type of model (quite possibly in a different "app")?

So, the fundamental question is this:

Is there a good way to use django ORM in a python library?

EDIT: This is not a duplicate of the CLI tool question. I know how to run django outside the web server. I even gave code samples showing this. I want to know if there's a way to run django where I don't have "apps" per se - where model files could be imported by client code and used in any order.

thegiffman
  • 465
  • 4
  • 8
  • Depends, What does your python library do? – Dean Christian Armada Jun 12 '16 at 06:28
  • I mean, I work for a VFX company and we'll be dealing with various internal databases, some HR related, some show related, etc. Various python applications will need to read or update from these. We'll want our shared python library to have nice pythonic objects to encapsulate this communication, rather than sprinkling SQL code throughout. Django seems to get us mostly there with its ORM. If it weren't for the call to setup or the INSTALLED_APPS, I'd say its exactly what we want. – thegiffman Jun 12 '16 at 06:40
  • Possible duplicate of [Using django for CLI tool](http://stackoverflow.com/questions/32088702/using-django-for-cli-tool) – e4c5 Jun 12 '16 at 14:33
  • Seeing that my question starts with similar code from that answer, I fail to see how it could be called a duplicate. I know the basic answer of how to run the ORM outside of a web server. I don't know if this is really viable in a library context, where I don't really have "apps" per se. – thegiffman Jun 13 '16 at 01:26
  • Then your question as it is, cannot still be called a good question. Instead of asking will it cause trouble, the simplest thing to do is to try it! If it causes trouble then you can come back here for a solution – e4c5 Jun 13 '16 at 02:05

1 Answers1

1

OK, here's my own attempt to answer the question after some research.

I can create a baseclass for my models anywhere in the library as follows:

from django.db import models
from django.apps import apps
import django.conf

django.conf_settings.configure(
    DATABASES = ...
)

apps.populate((__name__,))

class LibModel(models.Model):
    class Meta:
        abstract = True
        app_label = __name__

Then anywhere in the library I can create my own models with this baseclass. Since I'm not relying on the "app" for the database names, I need to state them explicitly.

class SpecificModel(LibModel):
    # fields go here
    class Meta(LibModel.Meta):
        db_table = "specific_model_table_name"

This gets around my concern of having to simulate the structure of an "app". The name property in the base class supplies Django with all it needs, and then Django quits whining about not finding an app. The other model files can live wherever they want.

However, there is still a big concern I have which might be lethal. Django's initialization itself is still singleton in nature. If my library were itself imported by a Django application, it would all crash and burn. I've asked for solutions to this in this follow up question.

Community
  • 1
  • 1
thegiffman
  • 465
  • 4
  • 8