Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用.using()优雅地处理OperationalError2003和更改数据库_Python_Mysql_Django_Python 3.x - Fatal编程技术网

Python 如何使用.using()优雅地处理OperationalError2003和更改数据库

Python 如何使用.using()优雅地处理OperationalError2003和更改数据库,python,mysql,django,python-3.x,Python,Mysql,Django,Python 3.x,假设您有一个Django 1.11应用程序,该应用程序在站点该站点上 在站点/settings.py中,您有以下数据库: DATABASES = { 'default': { 'ENGINE': 'django.db.back

假设您有一个Django 1.11应用程序,
该应用程序在站点
该站点

站点/settings.py
中,您有以下数据库:

DATABASES = {                                                                   
 'default': {                                                                
     'ENGINE': 'django.db.backends.mysql',                                   
     'NAME': 'the-site_webapp',                                                   
     'USER': 'tester',                                                       
     'PASSWORD': '',                                                         
     'HOST': 'localhost',                                                    
     'PORT': '3306',                                                                                                
 },                                                                          
 'remote-db1': {                                                                
     'ENGINE': 'django.db.backends.mysql',                                   
     'NAME': 'remote-db1',                                                      
     'USER': 'tester',                                                       
     'PASSWORD': '',                                                
     'HOST': '<ip1>',    
     'PORT': '3306',                                      
 },
 'remote-db2': {                                                                
     'ENGINE': 'django.db.backends.mysql',                                   
     'NAME': 'remote-db2',                                                      
     'USER': 'tester',                                                       
     'PASSWORD': '',                                                
     'HOST': '<ip2>',    
     'PORT': '3306',                                      
 },
}
指向app/routers.py的

class MasterRouter(object):                                                                                            
 '''                                                                         
 https://stackoverflow.com/questions/13988432/how-to-use-db-router-in-django-1-4
 '''                                                                         
 def __init__(self, app_label, db_name):                                     
     super(MasterRouter, self).__init__()                                    
     self.app_label = app_label                                              
     self.db_name = db_name                                                  


 def db_for_read(self, model, **hints):                                      
     if model._meta.app_label == self.app_label:                             
         return self.db_name                                                 
         #return self.app_label                                              
     return None                                                             

 def db_for_write(self, model, **hints):                                     
     if model._meta.app_label == self.app_label:                             
         return self.db_name                                                 

     return None                                                             

 def allow_relation(self, obj1, obj2, **hints):                              
     if obj1._meta.app_label == self.app_label or obj2._meta.app_label == self.app_label:
         return True                                                         
     return None                                                             

 def allow_syncdb(self, db, model):                                          
     if db == 'default':                                                     
         return model._meta.app_label == self.app_label                      
     elif model._meta.app_label == self.app_label:                           
         return False                                                        
     return None                                                             

 def allow_migrate(self, db, *args, **kwargs):                               
     if db in ['remote-db1']:                                            
         return False     


class DefaultRouter(MasterRouter):                                              
 def __init__(self):                                                         
     super(DefaultRouter, self).__init__('default', 'default')               

class the-appRouter(MasterRouter):                                                  
 def __init__(self):                                                                                       
     super(the-appRouter, self).__init__('the-app', 'remote-db1')                       
在app/views.py的
中,您有:

def foo (request):
    try:              
     curfile = ModelName.objects.get(**arg_dict)                            
     return _fetch_info(request, curfile)                                    
    except (KeyError, ModelName.DoesNotExist) as e:       
         messages.add_message(request, messages.ERROR, 'Couldn\'t find sample in remote-db1; attempting to connect to remote-db2')
         try:                                                                    
             curfile = ModelName.objects.using('remote-db2').get(**arg_dict)       
             return _fetch_info(request, curfile)                                
         except (KeyError, ModelName.DoesNotExist) as e:                        
             messages.add_message(request, messages.ERROR, 'Couldn\'t fetch sample data.')
             return render(request, 'foo.html')                            
         except (OperationalError,) as e:                                        
             messages.add_message(request, messages.ERROR, 'Couldn\'t connect to remote-db2.')
             traceback.print_exc() # debugging                                   
             return render(request, 'invalid.html')                              
     except (OperationalError) as e:                                             
          messages.add_message(request, messages.ERROR, 'Couldn\'t connect to remote-db1. Trying remote-db2.')
          traceback.print_exc() # debugging                                       
          try:                                                                    
             curfile = ModelName.objects.using('remote-db2').get(**arg_dict)       
             return _fetch_info(request, curfile)                                
          except (KeyError, SampleFile.DoesNotExist) as e:                          
              messages.add_message(request, messages.ERROR, 'Couldn\'t fetch sample data.')
              return render(request, 'view_info.html')                            
          except (OperationalError,) as e:                                        
              messages.add_message(request, messages.ERROR, 'Couldn\'t connect to either remote-db1 nor to remote-db2.')
              traceback.print_exc() # debugging                                   
              return render(request, 'invalid.html')
查看
traceback
日志,似乎发生了这样的情况:尽管我用
告诉Django。使用('remote-db2')
连接到
remote-db2
,它还是会再次尝试连接到
remote-db1

在我这方面,有没有什么地方可以处理这个操作错误(代码2003)?它(第205行)这可能是不可能的(),但必须有某种方式以某种方式优雅地处理此问题,而不是呈现一个错误页面,上面写着“稍后再试”

非常感谢您花时间阅读,以及您能给我的任何帮助:)

编辑:我既不管理旧数据库也不管理新数据库,因此我无法在数据库端轻松实现任何类型的负载平衡或故障切换策略。我被引导到django failover:github.com/brianjaystanley/django-failover(很抱歉,由于n00b状态,一篇文章中不能做超过2个链接),但我使用的是python 3.5,如果它仍然适用于django 1.11,则必须更新包!此外,两个远程数据库的模式略有不同,尽管它们包含关于相同对象的信息,因此django故障切换将不适用

相关职位:

  • stackoverflow.com/questions/18174910/django-database-routers-failover-scenario
  • stackoverflow.com/questions/28554740/in-django-1-6-handle-mysql-failover-while-use-database-routers

  • (我在写这篇文章之前读过其他人的文章,但问题与错误配置有关)

    你为什么要这样做?为什么不是一个数据库呢?我必须操作一个旧数据库和一个更新的数据库;传统数据库
    remote_db1
    ,包含一大堆大多数进程不再需要的表,而且由于记录的数量太多,很难进行搜索。较新的数据库
    remote_db2
    ,包含
    remote_db1
    中的数据截断(仅1个月前),以及原始表的子集。对一些表的模式也进行了一些小的更改。但是,如果旧数据库出现问题,那么我希望故障切换到新的数据库。为什么要这样做?为什么不是一个数据库呢?我必须操作一个旧数据库和一个更新的数据库;传统数据库
    remote_db1
    ,包含一大堆大多数进程不再需要的表,而且由于记录的数量太多,很难进行搜索。较新的数据库
    remote_db2
    ,包含
    remote_db1
    中的数据截断(仅1个月前),以及原始表的子集。对一些表的模式也进行了一些小的更改。但是,如果遗留数据库出现问题,那么我希望故障切换到新的数据库。
    def foo (request):
        try:              
         curfile = ModelName.objects.get(**arg_dict)                            
         return _fetch_info(request, curfile)                                    
        except (KeyError, ModelName.DoesNotExist) as e:       
             messages.add_message(request, messages.ERROR, 'Couldn\'t find sample in remote-db1; attempting to connect to remote-db2')
             try:                                                                    
                 curfile = ModelName.objects.using('remote-db2').get(**arg_dict)       
                 return _fetch_info(request, curfile)                                
             except (KeyError, ModelName.DoesNotExist) as e:                        
                 messages.add_message(request, messages.ERROR, 'Couldn\'t fetch sample data.')
                 return render(request, 'foo.html')                            
             except (OperationalError,) as e:                                        
                 messages.add_message(request, messages.ERROR, 'Couldn\'t connect to remote-db2.')
                 traceback.print_exc() # debugging                                   
                 return render(request, 'invalid.html')                              
         except (OperationalError) as e:                                             
              messages.add_message(request, messages.ERROR, 'Couldn\'t connect to remote-db1. Trying remote-db2.')
              traceback.print_exc() # debugging                                       
              try:                                                                    
                 curfile = ModelName.objects.using('remote-db2').get(**arg_dict)       
                 return _fetch_info(request, curfile)                                
              except (KeyError, SampleFile.DoesNotExist) as e:                          
                  messages.add_message(request, messages.ERROR, 'Couldn\'t fetch sample data.')
                  return render(request, 'view_info.html')                            
              except (OperationalError,) as e:                                        
                  messages.add_message(request, messages.ERROR, 'Couldn\'t connect to either remote-db1 nor to remote-db2.')
                  traceback.print_exc() # debugging                                   
                  return render(request, 'invalid.html')