Open Neamat opened 7 years ago
Are you sure your requests reach the middleware? https://github.com/stephane/django-db-multitenant/blob/stephane/fork/db_multitenant/middleware.py#L40
Thank you for your reply. The following is the error trace:
Unhandled exception in thread started by <function wrapper at 0x0000000003F77AC8>
Traceback (most recent call last):
File "C:\Python27\lib\site-packages\django\utils\autoreload.py", line 226, in wrapper
fn(*args, **kwargs)
File "C:\Python27\lib\site-packages\django\core\management\commands\runserver.py", line 116, in inner_run
self.check(display_num_errors=True)
File "C:\Python27\lib\site-packages\django\core\management\base.py", line 426, in check
include_deployment_checks=include_deployment_checks,
File "C:\Python27\lib\site-packages\django\core\checks\registry.py", line 75, in run_checks
new_errors = check(app_configs=app_configs)
File "C:\Python27\lib\site-packages\django\core\checks\model_checks.py", line 28, in check_all_models
errors.extend(model.check(**kwargs))
File "C:\Python27\lib\site-packages\django\db\models\base.py", line 1170, in check
errors.extend(cls._check_fields(**kwargs))
File "C:\Python27\lib\site-packages\django\db\models\base.py", line 1247, in _check_fields
errors.extend(field.check(**kwargs))
File "C:\Python27\lib\site-packages\django\db\models\fields\__init__.py", line 925, in check
errors = super(AutoField, self).check(**kwargs)
File "C:\Python27\lib\site-packages\django\db\models\fields\__init__.py", line 208, in check
errors.extend(self._check_backend_specific_checks(**kwargs))
File "C:\Python27\lib\site-packages\django\db\models\fields\__init__.py", line 317, in _check_backend_specific_checks
return connections[db].validation.check_field(self, **kwargs)
File "C:\Python27\lib\site-packages\django\db\backends\mysql\validation.py", line 18, in check_field
field_type = field.db_type(connection)
File "C:\Python27\lib\site-packages\django\db\models\fields\__init__.py", line 625, in db_type
return connection.data_types[self.get_internal_type()] % data
File "C:\Python27\lib\site-packages\django\db\__init__.py", line 36, in __getattr__
return getattr(connections[DEFAULT_DB_ALIAS], item)
File "C:\Python27\lib\site-packages\django\utils\functional.py", line 33, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "C:\Python27\lib\site-packages\django\db\backends\mysql\base.py", line 184, in data_types
if self.features.supports_microsecond_precision:
File "C:\Python27\lib\site-packages\django\utils\functional.py", line 33, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "C:\Python27\lib\site-packages\django\db\backends\mysql\features.py", line 53, in supports_microsecond_precision
return self.connection.mysql_version >= (5, 6, 4) and Database.version_info >= (1, 2, 5)
File "C:\Python27\lib\site-packages\django\utils\functional.py", line 33, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "C:\Python27\lib\site-packages\django\db\backends\mysql\base.py", line 359, in mysql_version
with self.temporary_connection():
File "C:\Python27\lib\contextlib.py", line 17, in __enter__
return self.gen.next()
File "C:\Python27\lib\site-packages\django\db\backends\base\base.py", line 564, in temporary_connection
cursor = self.cursor()
File "C:\Python27\lib\site-packages\django\db\backends\base\base.py", line 231, in cursor
cursor = self.make_debug_cursor(self._cursor())
File "C:\Python27\lib\site-packages\db_multitenant\db\backends\mysql\base.py", line 56, in _cursor
cursor = super(DatabaseWrapper, self)._cursor()
File "C:\Python27\lib\site-packages\django\db\backends\base\base.py", line 204, in _cursor
self.ensure_connection()
File "C:\Python27\lib\site-packages\django\db\backends\base\base.py", line 199, in ensure_connection
self.connect()
File "C:\Python27\lib\site-packages\django\db\backends\base\base.py", line 173, in connect
self.init_connection_state()
File "C:\Python27\lib\site-packages\django\db\backends\mysql\base.py", line 270, in init_connection_state
with self.cursor() as cursor:
File "C:\Python27\lib\site-packages\django\db\backends\base\base.py", line 231, in cursor
cursor = self.make_debug_cursor(self._cursor())
File "C:\Python27\lib\site-packages\db_multitenant\db\backends\mysql\base.py", line 65, in _cursor
raise ImproperlyConfigured('dbname not set at cursor create time')
django.core.exceptions.ImproperlyConfigured: dbname not set at cursor create time
I guess it doesn't go to the middleware but I added the middleware as the first one in the middleware section. The following is the middleware section:
MIDDLEWARE_CLASSES = [
'db_multitenant.middleware.MultiTenantMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
The following also is the database:
DATABASES = {
'default': {
#'ENGINE': 'django.db.backends.mysql',
'ENGINE': 'db_multitenant.db.backends.mysql',
'NAME': 'tenant',
'USER': 'tenantuser',
'PASSWORD': 'tenantpwd',
'HOST': 'localhost',
'PORT': '3306',
}
}
Please advise what would be the issue.. Thanks alot @stephane
How do you access your application (hostname)?
Thank you for replying Stephane and please help me because I can't access it yet. I just try to run "runserver" just to open the server and I get that error so I can't even make it work to start accessing it from the browser. I also added a fixed name for the database inside the mapper so that I remove the possibility that the mapper would be the issue. But apparently it doesn't even reach the mapper. What do you think I should do to know the problem? My initial thought is that it can't even connect to the default database however I already have other projects that can connect without any issues so it's not MySQL connection.
On 27 April 2017 at 12:28, Stéphane Raimbault notifications@github.com wrote:
How do you access your application (hostname)?
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/mik3y/django-db-multitenant/issues/16#issuecomment-297676050, or mute the thread https://github.com/notifications/unsubscribe-auth/AJlKQDxU41lE7igqQOnONL98KTUW6zlyks5r0G3PgaJpZM4M4h6a .
-- Neamat El Tazi Assistant Professor, Faculty of Computers and Information, Cairo University, Egypt Email: n.eltazi@fci.edu.eg
--
I have been tearing my hair out with this issue too... Adding print statements I can see that the DatabaseWrapper._cursor() method gets called several times at 'bootup', i.e. before any requests are sent, during which time the middleware is not even loaded (and so db_name is not set on thread_local, hence the exception).
Funnily enough DatabaseWrapper._cursor()
doesn't seem to be called at all on requests, so I have just removed the exception raising and it seems to works fine (in debug on local, not tried on prod), which makes me wonder if there's any point it being there at all?
Edit: sorry, the above is incorrect. DatabaseWrapper._cursor()
does get called in requests (that's what placing print statements when pulling an all-nighter will do to you!) but during 'bootup' it won't find the db_name on threadlocal because the middleware only kicks in and sets that when it receives requests.
The db queries which run at boot up prior to any requests are SET SQL_AUTO_IS_NULL = 0
and such. And it seems that these are only called on MYSQL and people have asked for them to be removed as they are aparently unecessary, and this may be the case on newer versions of django (see this post) which would explain why some people see this error, but others don't.
If my understanding is correct:
I'm wondering if we should raise the ImproperlyConfigured()
exception in MultiTenantMiddleware.process_request()
instead, which would resolve this issue. And replace the exception in DatabaseWrapper._cursor()
with a printed warning because that will only happen if we haven't set in ENV, which infers we're using it from a manage.py command. But perhaps I'm missing something?
Using django 1.9.5
I've solve this issue setting the TENANT_DATABASE_NAME
var to my main db. Nevertheless I'm not sure either why is not getting the correct database name.
I am also getting the same issue
raise ImproperlyConfigured('dbname not set at cursor create time').
Is there any solution.
I created a fork which I'm using as a workaround: https://github.com/andyhasit/django-db-multitenant
having same error on django 1.9
@andyhasit that means you want to fallback to the default DB when not set?
@stephane Yes, and that's what my fork does.
@andyhasit could you propose a PR against master, please?
I solve this problem adding:
'db_multitenant.middleware.MultiTenantMiddleware',
To the first MIDDLEWARE, as say the documentation:
Don't forget add in settings.py at the end file :
from db_multitenant.utils import update_from_env
update_from_env(database_settings=DATABASES['default'],
cache_settings=CACHES['default'])
I followed all the steps that you mentioned in your docs but I always get the same error "dbname not set at cursor create time" when I run the project. I even sent a static database name inside the mapper just to try it and it returned the same error. It looks like it cannot initiate with the default database that I already added inside the settings. Any suggestions?