本人python新手一枚,因业务需要使用到Django服务器。最先开始使用的是,单个数据库,因为Django当中对于单个APP对应单个数据库的情况,无需过多配置,所以本人并未花很长时间去配置数据库,直到今天业务需求改成了,单个APP对应多个数据库,因为是自学,所以只能上网查阅资料。陆续看了很多资料,也感谢各种大佬们提供的解决方案,也走过很多坑,历时四个小时最终搞定。
坑1
多个数据库的情况和单个的不一样。单个数据库无需额外创建APP,而多个数据库的情况,需要针对每个数据库都创建一个单独的APP。
坑2
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# 'DjangoApp',
# 'db1_app',
# 'db2_app',
]
settings 当中不要注册任何的APP ,否则会在cmd 运行
python3.9 manage.py makemigrations 报一个重复注册DjangoApp的错误,注释掉所有的APP后程序顺利运行
坑3
DATABASES = {
'default': {},
'db1': {
'ENGINE': 'django.db.backends.mysql', # 使用的数据库引擎
'NAME': '手机cookie', # 数据库名称
'USER': '手机cookie', # 数据库用户名
'PASSWORD': 'NFjrpk8SxEb8h4J4', # 数据库密码
'HOST': '127.0.0.1', # 数据库服务器地址
'PORT': '3306', # 数据库端口(如果有必要)
'OPTIONS': {
'charset': 'utf8mb4', # 或者 'utf8',根据 MySQL 版本和需求选择
'init_command': "SET collation_connection = 'utf8_general_ci'",
},
},
'db2': {
'ENGINE': 'django.db.backends.mysql',
'NAME': '手机cookie_2',
'USER': '手机cookie_2',
'PASSWORD': 'AABEAEH2Gc3wNXH4',
'HOST': '127.0.0.1',
'PORT': '3306',
'OPTIONS': {
'charset': 'utf8mb4', # 或者 'utf8'
'init_command': "SET collation_connection = 'utf8_general_ci'",
},
},
}
#单个APP 如果要设置多个数据库 得在这里写上路由
DATABASE_APPS_MAPPING = {
"db1_app": "db1", # db1_app 对应 db1 数据库
"db2_app": "db2" # db2_app 对应 db2 数据库
}
DATABASE_ROUTERS = ['DjangoPro.database_router.DatabaseAppsRouter']
注意把default留空
坑4
#!/usr/bin/env python3.5
# -*- coding:utf-8 -*-
"""
file: database_router.py
date: 20180801
author: S_L_zheng@163.com
function: Multi-database use.
"""
from django.conf import settings
DATABASE_MAPPING = settings.DATABASE_APPS_MAPPING
class DatabaseAppsRouter(object):
"""
A router to control all database operations on models for different
database.
In case an app is not set in setting.DATABASE_APPS_MAPPING, the router
will fallback to the 'default' database.
Settings example:
DATABASE_APPS_MAPPING = {'app1': 'db1', 'app2': 'db2'}
"""
def db_for_read(self, model, **hints):
"""Point all read operations to the specific database."""
if model._meta.app_label in DATABASE_MAPPING:
return DATABASE_MAPPING[model._meta.app_label]
return None
def db_for_write(self, model, **hints):
"""Point all write operations to the specific database."""
if model._meta.app_label in DATABASE_MAPPING:
return DATABASE_MAPPING[model._meta.app_label]
return None
def allow_relation(self, obj1, obj2, **hints):
"""Allow any relation between apps that use the same database."""
db_obj1 = DATABASE_MAPPING.get(obj1._meta.app_label)
db_obj2 = DATABASE_MAPPING.get(obj2._meta.app_label)
if db_obj1 and db_obj2:
if db_obj1 == db_obj2:
return True
else:
return False
return None
# Django 1.7 - Django 1.11
def allow_migrate(self, db, app_label, model_name=None, **hints):
print(db, app_label, model_name, hints)
if db in DATABASE_MAPPING.values():
return DATABASE_MAPPING.get(app_label) == db
elif app_label in DATABASE_MAPPING:
return False
return None
上网部分资料当中的数据库路由是不可用的,我是在宝塔服务器当中部署的Django,因为宝塔的ide的识别不到错误代码,导致有些标红一大片的代码段被我直接粘贴到服务器中,调试多次后仍然失败。
坑5
#db1_app
class MyModel(models.Model):
# id = models.AutoField(primary_key=True)
update_time = models.TextField()
nick = models.TextField()
cookie = models.TextField()
class Meta:
app_label = 'db1_app'
db_table = '手机cookie'
#db2_app
class MyModel_2(models.Model):
# id = models.AutoField(primary_key=True)
update_time = models.TextField()
nick = models.TextField()
cookie = models.TextField()
class Meta:
app_label = 'db2_app'
db_table = '手机cookie_2'
meta 当中app_label 和 db_table 都不能省 省一个就报错
坑6
from db1_app.models import MyModel
from db2_app.models import MyModel_2
@csrf_exempt
def PhoneCkUpload(request):
try:
updatetime = datetime.datetime.now()
tz_offset = datetime.timedelta(hours=8) # UTC+8:00,即中国上海时区
updatetime = datetime.datetime.now(datetime.timezone(tz_offset))
updatetime = re.findall('(.*)\.', str(updatetime))[0]
data = json.loads(request.body)
nick = data.get('nick')
cookie = data.get('cookie')
nick = unquote(nick)
#cookie = unquote(cookie)
if updatetime and nick and cookie:
try:
# with transaction.atomic():
# MyModel.objects.create(update_time=updatetime, nick=nick, cookie=cookie)
obj = MyModel(update_time=updatetime, nick=nick, cookie=cookie)
obj.save()
return JsonResponse({'message': 'Data written successfully!'})
except Exception as e:
return JsonResponse({'error': str(e)}, status=500)
else:
return JsonResponse({'error': 'Missing required fields.'}, status=400)
except Exception as e:
print(f"Exception occurred: {str(e)}")
return JsonResponse({'error': 'Internal Server Error222.'}, status=500)