Connecting and importing models from multiple database connections Django - django

In a django app, I have two postgresql databases connected through settings.py: one is default and other is AppDb. AppDb is placed on a remote machine.
I want to query from a 'Courses' model from AppDb using 'using()' and 'Courses' model is not available in default database.
So my query goes like this:
courseInfo = Courses.objects.using('AppDb').filter(cuser_id = 12)
But I am getting NameError for 'Courses'
Can I have a solution for such queries without using routers

If you have an existing database, you still need to create an app and models for that database in order to use the ORM.
To help you create the model classes, you can use the inspectdb management command which will try to guess the models from an existing database and create the models.py for you. Its not perfect, but it will save you some time.
You will still have to make sure the models have a primary key and are written in the correct order (so that foreign keys will work correctly).

Related

Django: Force create index on ForeignKey fields when db's `supports_foreign_keys=False`

I'm trying to use Django (v4.1.3) with Planet Scale's DB which is MySQL compliant with the relevent exception of not supporting foreign keys.
For this, they provide a Django DB driver which subs class the MySQL DB feature class
from django.db.backends.mysql.features import \
DatabaseFeatures as MysqlBaseDatabaseFeatures
class DatabaseFeatures(MysqlBaseDatabaseFeatures):
supports_foreign_keys = False
Given this, when I generate migrations and apply them on my local MySQL server, I don't see any foreign keys being created as expected. However, I also don't see keys being created but I still want the keys.
For example with the MySQL driver, when I run SHOW CREATE app_user_groups (from django.contrib.auth package) I see the following key:
CREATE TABLE `auth_group_permissions` (
...
KEY `auth_group_permissio_permission_id_84c5c92e_fk_auth_perm` (`permission_id`),
)
But with the Planet Scale driver (supports_foreign_keys = False), Django doesn't create an key/index.
I know in my models, I can explicitly define keys but I don't find this ideal. In addition, I don't have control over models from other Django apps like django.contrib.auth and many other 3rd party ones.
What can I do to make Django create keys on django.db.models.ForeignKey despite support for foreign keys being off.

Do i need models.py even for ready made mysql databases?

I spin up a django project. Afterwards, i didn't write models.py but instead I created a database from MySQL command line(independent from django) and created three tables with required columns. Finally i connected my django app with that database successfully. I applied migrations. But now i am confused do i need to write models.py with every field name as in column?
I remember implementing a basic project in which i did write models.py and created database using "python manage.py shell" and then put values using
"from polls.models import Choice, Question"? How do i put data now initially and then using python on some action from UI?
Do i need models.py even for ready made mysql databases?
You do not need to construct models. Some (small) webservers are even completely stateless, and thus do not use a database. But a large part of how Django can help you is based on models.
You can write your own queries, forms, etc. But often by using a ModelForm, Django can for example remove a large amount of boilerplate code. It will make it furthermore less likely that there are mistakes in your code. So although not strictly necessary, the models are usually a keystone in how Django can help you.
You can use the inspectdb [Django-doc] command to inspect the database, and let Django "sketch" the models for you. Usually you will have still some work. Since Django can, for example, not derive that a field is an EmailField, since both a CharField and EmailField look exactly the same at the database side.
You do not need to use inspectdb however. You can construct your own models. If you create your own models, but these exist already at the database side, you might want to set managed = False [Django-doc] in the Meta of your model, to prevent Django from constructing migrations.

How to dynamically swap default database on the model manager in django?

I am creating a project in django and django rest framework. Its an api for an angular app. The database setup consists of multiple databases. one is default database, all the django tables reside in this database; rest of the databases belong to a type of a user, each user is supposed to have a separate database. So, all the user related data goes to its separate database. To implement the selecting database dynamically, user object has an extra field to store the database to write to.
from django.contrib.auth.models import AbstractUser
class CustomUser(AbstractUser):
"""Custom User model."""
database= models.CharField(max_length=9)
Reason for doing this was performance improvement as each database is separate, ListView and DetailView would work faster than if the data was stored in the one database only.
I know I can choose a database to store by using the using method on the model manager. In the rest api things work fine and data is being stored in their separate databases, but I end up overriding methods that django has defined. Its adding development cost to the project. Foreign keys and ManytoMany keys needs to be resolved with the current database of the user, which is not happening as I have customized the database setup. Also, my code cant be as good as theirs :p , as they have written django over the course of many years.
I have overwritten many querysets already, but django still uses default database many times. If only I could use the request object in the model manager of django models to swap the default database on per request basis, things would be different i think.
My questions are -
Is there a way to access the request object in the model manager? I could do something to the effect of below code.
class CustomManager(models.Manager):
def get_queryset(self, request):
return super(CustomManager, self).using(request.user.database).get_queryset()
Model manager has _db property that could be used to select database. Would overriding it is advised? if yes, how and where in the code?
Is there a better way to implement the separate databases?
Thanks in advance.
Regards
Using a database router is recommended in Django docs, but the problem is it only accesses the model class.
Found a couple of questions related to the problem of switching databases dynamically. This post has a solution that would solve the problem of passing the request.user or any other parameter by using a threading.local instance.
Someone created a reusable plugin even for this - https://github.com/ambitioninc/django-dynamic-db-router
Hope that helps.

Use Models with a moving/different Sqlite databases?

I am looking to have a django app that visually displays a SQLite database. The idea is that the user would pass in the path to the sqlite file in the URL for the app. I was wondering if I could make use of the Django models and use something like django-tables2 to display it. I was just wondering if the Models are not setup in models.py prior to the start of the server.
Is there a way to still use Model, read/write to the given database and be able to still build the table?

Tying a model to a specific database alias

I have defined two databases in my settings.py with default, cas.
In my accounts application models.py I have created two clases
UserProfile and Users.
I want to tie UserProfile table to default and Users to cas db setting:
so for e.g. when I do a syncdb using the following command
python manage.py syncdb --database=cas
it should create only the users table in CAS and not the UserProfile table too.
Is there a way I can achieve this?
Take a look at the Database routing features of Django 1.2. You'll likely find what you need:
http://docs.djangoproject.com/en/dev/topics/db/multi-db/#automatic-database-routing