*First of all, I’m using versions of Python 3.5 and Django 2.0.4, and the company is using Django, not restframework.
I. application scenarios
First, a Django project usually has multiple apps, and now many companies share a common database of these apps. There are no so-called multiple databases in this scenario. In my personal experience, the company has made some small systems in the past two months.It’s all for sorting data inside the company), because each is in a hurry, so it’s done one online, and the database and the project are on different servers. Until one day our boss called me over: “Xiao Xiao, you take the time to put together a few of the systems you’ve done, let’s synthesize them into one system.After landing, a system selection page will be selected, and which system will be selected.
After that, I fought hard to merge the code. However, the data is not found in a warehouse, Wang fried! Then there are two options:
1.Put all the models together through the default database, then you need to extract the previously processed data, and modify the model to make some distinctions between duplicate table names;
2.It is to still keep the data in the previous library, migrate these databases out, extract Django self-built tables, and then through different databases for different operations, which also achieves data isolation between different systems.
So in the end, I chose second schemes to do this.
Two. Code implementation
The code is mainly composed of three parts, settings, models and a class written by oneself. First, look at the class we wrote:
1 from django.conf import settings
2
3 DATABASE_MAPPING = settings.DATABASE_APPS_MAPPING
4
5 class DatabaseAppsRouter(object):
6 """
7 A router to control all database operations on models for different
8 databases.
9
10 In case an app is not set in settings.DATABASE_APPS_MAPPING, the router
11 will fallback to the `default` database.
12
13 Settings example:
14
15 DATABASE_APPS_MAPPING = {'app1': 'db1', 'app2': 'db2'}
16 """
17
18 def db_for_read(self, model, **hints):
19 """"Point all read operations to the specific database."""
20 """Point all read operations to a specific database."""
21 if model._meta.app_label in DATABASE_MAPPING:
22 return DATABASE_MAPPING[model._meta.app_label]
23 return None
24
25 def db_for_write(self, model, **hints):
26 """Point all write operations to the specific database."""
27 """Writes all operations to a specific database."""
28 if model._meta.app_label in DATABASE_MAPPING:
29 return DATABASE_MAPPING[model._meta.app_label]
30 return None
31
32 def allow_relation(self, obj1, obj2, **hints):
33 """Allow any relation between apps that use the same database."""
34 """Any relationship between applications that allow the same database to be used"""
35 db_obj1 = DATABASE_MAPPING.get(obj1._meta.app_label)
36 db_obj2 = DATABASE_MAPPING.get(obj2._meta.app_label)
37 if db_obj1 and db_obj2:
38 if db_obj1 == db_obj2:
39 return True
40 else:
41 return False
42 else:
43 return None
44
45 def allow_syncdb(self, db, model):
46 """Make sure that apps only appear in the related database."""
47 """Ensure that these applications are only present in the relevant database."""
48 if db in DATABASE_MAPPING.values():
49 return DATABASE_MAPPING.get(model._meta.app_label) == db
50 elif model._meta.app_label in DATABASE_MAPPING:
51 return False
52 return None
53
54 def allow_migrate(self, db, app_label, model=None, **hints):
55 """Make sure the auth app only appears in the 'auth_db' database."""
56 """Make sure that the authentication application appears only in the "authdb" database."""
57 if db in DATABASE_MAPPING.values():
58 return DATABASE_MAPPING.get(app_label) == db
59 elif app_label in DATABASE_MAPPING:
60 return False
61 return None
This class mainly standardizes some read-write operations of the database. Note that this file is placed in the same directory as settings.py. Code logic is easy to understand, and I will not explain it. When you use it, copy and paste a shuttle directly, then you can do some logical processing modifications again.That’s right.
In settings, three places are configured. The code is as follows:
1 # Database
2 # https://docs.djangoproject.com/en/2.0/ref/settings/#databases
3
4 DATABASES = {
5 'default':{
6 'NAME': 'venn',
7 'ENGINE': 'sql_server.pyodbc',
8 'HOST': '127.0.0.1',
9 'PORT': '1433',
10 'USER': 'venndata',
11 'PASSWORD': 'venndata',
12 'OPTIONS':{
13 'driver':'SQL Server Native Client 10.0',
14 }
15 },
16 'venn': {
17 'NAME': 'venn',
18 'ENGINE': 'sql_server.pyodbc',
19 'HOST': '127.0.0.1',
20 'PORT': '1433',
21 'USER': 'venndata',
22 'PASSWORD': 'venndata',
23 'OPTIONS':{
24 'driver':'SQL Server Native Client 10.0',
25 }
26 },
27 'vip_cluster': {
28 'NAME': 'vip_cluster',
29 'ENGINE': 'sql_server.pyodbc',
30 'HOST': '127.0.0.1',
31 'PORT': '1433',
32 'USER': 'venndata',
33 'PASSWORD': 'venndata',
34 'OPTIONS':{
35 'driver':'SQL Server Native Client 10.0',
36 }
37 },
38 'catecheck': {
39 'NAME': 'catecheck',
40 'ENGINE': 'sql_server.pyodbc',
41 'HOST': '127.0.0.1',
42 'PORT': '1433',
43 'USER': 'venndata',
44 'PASSWORD': 'venndata',
45 'OPTIONS':{
46 'driver':'SQL Server Native Client 10.0',
47 }
48 },
49 'skucheck': {
50 'NAME': 'skucheck',
51 'ENGINE': 'sql_server.pyodbc',
52 'HOST': '127.0.0.1',
53 'PORT': '1433',
54 'USER': 'venndata',
55 'PASSWORD': 'venndata',
56 'OPTIONS':{
57 'driver':'SQL Server Native Client 10.0',
58 }
59 },
60 'barcode': {
61 'NAME': 'barcode',
62 'ENGINE': 'sql_server.pyodbc',
63 'HOST': '127.0.0.1',
64 'PORT': '1433',
65 'USER': 'venndata',
66 'PASSWORD': 'venndata',
67 'OPTIONS':{
68 'driver':'SQL Server Native Client 10.0',
69 }
70 }
71 }
72
73
74 DATABASE_ROUTERS = ['vennsystem.database_router.DatabaseAppsRouter']
75
76
77 DATABASE_APPS_MAPPING = {
78 # example:
79 # 'app_name':'database_name',
80 'venncheck': 'skucheck',
81 'barcode': 'barcode',
82 'catecheck': 'catecheck',
83 'clust': 'vip_cluster',
84 'the_entrance': 'venn',
85 'admin': 'venn',
86 'auth': 'venn',
87 'contenttypes': 'venn',
88 'sessions': 'venn',
89 }
DATABASESAs you all know, it is to configure the database connection. (Note here that I use the SQL Server database, where OPTIONS is a very important parameter, you must add this, or you won’t be able to run.) Default is the default database, where {} can be used.But once it’s empty, you can’t execute’python manage. py migrate'(what will be done in the next section)
Then DATABASE_ROUTERS points to the class we wrote ourselves ([‘project name, file name, class name’]).The last is routing allocation, which corresponds to the name of app and database.
The part of the model is very simple, and it can be solved by adding two lines of code.
1 class Href(models.Model):
2 name = models.CharField(max_length=100)
3 path = models.CharField(max_length=100)
4
5 class Meta:
6 app_label = 'the_entrance'
It is such a thing, plus app_label, will specify the app.
Three. Implementation
The order of execution is familiar to everyone.
1.python manage.py makemigrations
Then it is slightly different.
2.python manage.py migrate –database=skucheck
python manage.py migrate –database=barcode
……
python manage.py migrate(Only when the default database is not empty can it be practical.
There is no specific execution sequence here, but I personally recommend that you do migrate last. Another thing to note is admin.auth、contenttypesAnd sessions must be placed in an app by makemigrations in a XXXX_initial.py file, otherwise you can migrate without these Django self-built tables!