Django MySQL schema selection - python

In the same MySQL server we have a database for each client. This databases share the same table structure. We were able to create a Model for table Foo that looks like this:
class Foo(models.Model):
id = models.AutoField(primary_key=True)
bar = models.CharField(max_length=50)
class Meta:
managed = False
db_table = 'foobar'
Our Django project needs to manage all of our clients. As all of them have the same structure we would also like to share the Foo model. At the begging we were able to handle this issue by defining in the project settings each client's database and using routers. At the moment we have too many clients to have them all defined in setting.py.
Is there any reasonable way to tell the model which schema has to be used every time we use it?

Related

Is there a way to share a common table of database between two django projects without faking it?

I am trying to use a same table across two different projects and want to reflect the changes between them.
Let's assume that there is a student table in the data created by PROJECT1-APP1 of django. I want that same student table to use in PROJECT2-APP1. I have searched the interned and get recommendation to import the model from 1 project to other but according to my understanding it is just "faking" it and some functionality like BigAutoFeild and Foreign Keys would not work in this solution. Is there a way that I can use the same database in two different projects which will not mess up with the core operation?
EDIT:
the other questions just shows how to connect database which I know, the problem occurs when I try to use the same tables.
You may need to create a model in the other app and explicitly specify the database table in the class Meta section. Similar to below:
class Person(models.Model):
id = models.IntegerField(primary_key=True)
first_name = models.CharField(max_length=70)
class Meta:
db_table = 'table_persons'

How can I see data from an already made mysql database on Django?

I'm new to Django and I am trying to use a mysql database created and filled with data by someone else
I created a model with the same name as the table I want to get data from, my models is as follows
class Study(models.Model):
study_name = models.TextField(default='Unknown')
description = models.TextField(default='Unknown')
language = models.TextField(default='Unknown')
number_of_years = models.IntegerField(default='0')
database connected but when I go to admin I don't see the data there
Please help me with this
A step by step solution would be:
get the name of the table containing your data, I'll call it study_table
make sure you know how the table was defined so you can match it with django model definition. Connect to the database with a MySQL client and run the following query:
DESCRIBE study_table;
based on the table name, column types and column names, define your model to match everything. Django models do a lot of automated naming so you have force the naming to make sure your model matches your database. Principles are:
Specify the table name as a meta option.
Create fields with names matching column names and field types matching column types. Taking an example from your code, the field study_name should match a column with the same name in the table study_table.
class Study(models.Model):
study_name = models.TextField(default='Unknown')
description = models.TextField(default='Unknown')
language = models.TextField(default='Unknown')
number_of_years = models.IntegerField(default=0)
class Meta:
db_table = study_table
Side note: your IntegerField has a default as a string '0'.
making sure the app (I'll call it study_app) containing your model is enabled, the database is configure properly in your django settings, try to access data from the admin shell (python manage.py shell):
>>> from study_app.models import Study
>>> Study.objects.first()
This should return an answer, if it does not, your model doesn't match the database data.
to make accessing the data easier, create an admin page as suggested by #iklinac. You can now read, edit your data through your browser.
A few suggestions you could consider:
study_name should probably be a models.CharField(max_length=255) or similar
description should be allowed to be empty models.TextField(blank=True)
language should probably be a models.CharField with a choices option.
You should create ModelAdmin instance for your model
The ModelAdmin class is the representation of a model in the admin
interface. Usually, these are stored in a file named admin.py in your
application.
from django.contrib import admin
from myproject.myapp.models import Study
class StudyAdmin(admin.ModelAdmin):
pass
admin.site.register(Study, StudyAdmin)
If you have a MySQL database with tables of data that don't have models created yet, you can use the dumpdata command to automatically generate the models:
https://docs.djangoproject.com/en/3.0/ref/django-admin/#dumpdata
Then, you can register those models in the Django admin. dumpdata should only be used as a starting point, since they are auto-generated and won't contain many of Django's data integrity features.
Good luck!

How to change the table names after "makemigrations"

Whenever I make migrations, Django automatically attaches the name of my application to database tables. For example, if I have application myapp and there is a model named Model1, then after migrations the database table name will be myapp_model1.
I don't need app name along with table name. If someone knows how to change it then please help me.
My advice is to let Django choose the table names automatically. Having the application name as a prefix means that you can have two models with the same name in different applications, but their database table names will not clash.
If you really want to change the table name, you can use the db_table option to set the table name in the database.
class MyModel(models.Model):
name = models.CharField(max_length=50)
...
class Meta:
db_table = 'mymodel'
This might be tricky if the database tables have already been created. To avoid problems, I would only set the db_table option for a new application.

foreign keys between databases with peewee

I have two legacy MySQL databases for which I'd like to define an ORM class-model in peewee (python). Specifically, one database holds front-end data, the other back-end data and some information between the tables of the databases are linked with foreign keys from one database to the other.
Example code (not the actual code, inspired by the example in quick start):
import peewee
frontend = peewee.MySQLDatabase('frontend', host=host, user=user, passwd=passwd)
backend = peewee.MySQLDatabase('backend', host=host, user=user, passwd=passwd)
class User(peewee.Model):
name = peewee.CharField()
class Meta:
database = frontend
class Tweet(peewee.Model):
user = peewee.ForeignKeyField(User, related_name='tweets')
content = peewee.TextField()
class Meta:
database = backend
Going through the docs, I couldn't find a direct way to link the foreign keys between tables. Also, I've tried generating a peewee model using the supplied pwiz.py script, which worked successfully on the front-end database, but not on the back-end (probably because the back-end only seems to refer to the front-end and not vice-versa). Nevertheless, I'd like to ask whether such a model with two databases is possible.
Peewee does not support foreign keys across multiple databases.

If I need a database view or not?

I have these models:
class Company(models.Model):
name=models.CharField(max_length=100)
description=models.TextField()
#some more fields
class Product(models.Model):
name=models.CharField(max_length=100)
company=models.ForeignKey(Company)
#some more fields
class Category(models.Model):
parent=models.ForeignKey('self',null=True,blank=True)
name=models.CharField(max_length=100)
products=models.ManyToManyField(Product,null=True,blank=True)
#some more fields
as U can see each company has a list of product and each product belongs to some categories,I'm going to get the list of categories of each company using company pk,what's the best practice?should I define a database view?how can I do this?
Note:I've not ever used database view in django,I searched about it and that doesn't sound easy to me!
I always try to avoid using database views, stored procedures and in general stuff that 'lives' in the database itself rather than in the application code-base for the simple reason that it is very hard to maintain (and also you say good bye to database agnostic applications).
My advice here is to stick with django orm (which can do a lot) and only if you unable to get decent performances or if you need some advanced feature available through stored procedures/views only then to go for that solution.
Using views in django is quite easy.
Say you have 1 view to query, you create the view on the db then you write the model with fields matching the view' columns (name and type).
UPDATE:
You then need to set the table name as the view name in meta class definition.
After that you need to tell django not to write on that and to not try to create a table for the view model, luckily there is a conf for that:
class ViewModel(models.Model):
... view columns ...
class Meta():
db_table = 'view_name'
managed = False
I've no idea why you think you need a db view here. Generally, you don't use them with Django, since you do all the logic in Python via the ORM.
To get the list of categories for a company, you can just do:
categories = Category.objects.filter(products__company=my_company)
where my_company is the Company instance you're interested in.

Categories