I'm testing my code on Windows 10. I have a Django application that needs to call a stored procedure on a remote SQL Server database. Here's the DATABASES snippet from settings.py:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'db1',
'HOST': 'mycompany.com',
'PORT': '3306',
'USER': 'user',
'PASSWORD': 'pw',
},
'ss': {
'ENGINE': 'django_pyodbc',
'NAME': 'db2',
'HOST': 'myserver\SQLEXPRESS',
'USER': 'myuser',
'PASSWORD': 'mypw',
'PORT': '1433',
# 'DRIVER': 'SQL Server',
'OPTIONS': {
'driver_supports_utf8': True,
'host_is_server': True, # must be True for remote db
'autocommit': True,
'unicode_results': True,
'extra_params': 'tds_version=8.0',
},
},
}
Here's a code snippet from my view:
cursor = connections['ss'].cursor()
cursor.execute("{call dbo.mysproc(?)}", (id))
When I execute the cursor.execute statement I get this error:
django.db.utils.DatabaseError: ('The SQL contains 1 parameter markers,
but 36 parameters were supplied', 'HY000')
My parameter, id, is a GUID.
Thoughts?
Here's the fix, simply changed the parentheses surrounding the parameter to square brackets:
cursor.execute("{call dbo.mysproc(?)}", [id])
I found this by trial and error.
Related
On migrate step I get such error django.db.utils.OperationalError: ERROR: unsupported startup parameter: options
settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'OPTIONS': {
'options': '-c search_path=public'
},
'NAME': env.str('DB_NAME'),
'USER': env.str('DB_USER'),
'PASSWORD': env.str('DB_PASS'),
'HOST': env.str('DB_HOST'),
'PORT': env.str('DB_PORT'),
'DISABLE_SERVER_SIDE_CURSORS': True,
}
}
(in options parameter I tried to set default schema to public)
Can this error appear because I have pgbouncer?
I am using Django to connect to an on-premise database. Earlier, the database was hosted on Azure.
The connection string I used within Django settings earlier was as follows-
for sql database of Azure
DATABASES = {
'default': {
'ENGINE': 'sql_server.pyodbc',
'NAME': 'DatabaseName', #notrealname
'USER': 'username',
'PASSWORD': 'password',
'HOST': 'sql-django-uat.database.windows.net', #notreal
'PORT': '1433',
'OPTIONS': {
'driver': 'ODBC Driver 13 for SQL Server',
'MARS_Connection': 'True',
}
After the database migration, this string doesnt work. I keep getting 'Login timeout expired'.
But substituting 'NAME' with "DATABASE' works. Example given below-
DATABASES = {
'default': {
'ENGINE': 'sql_server.pyodbc',
'DATABASE': 'DatabaseName', #notrealname
'USER': 'username',
'PASSWORD': 'password',
'HOST': 'on-prem.local',
'PORT': '1433',
'OPTIONS': {
'driver': 'ODBC Driver 13 for SQL Server',
'MARS_Connection': 'True',
}
My webapp gets to the login page. But after I log in, I get the error- 'ImproperlyConfigured at /login/
settings.DATABASES is improperly configured. Please supply the NAME value.'
Can someone tell me how to solve this? I should mention leaving the "NAME" field blank also gives the same error. Thanks so much in advance.
DATABASES = {
'default': {
'ENGINE': 'sql_server.pyodbc',
'NAME': 'DatabaseName', #notrealname
'USER': '<replace with on-premise DB Username>',
'PASSWORD': '<replace with on-premise DB password>',
'HOST': '<replace with database URL of on-premise DB URL>',
'PORT': '1433',
'OPTIONS': {
'driver': 'ODBC Driver 13 for SQL Server',
'MARS_Connection': 'True',
}
From the Azure SQL database, the settings.py should be:
DATABASES = {
'default': {
'ENGINE': 'sql_server.pyodbc',
'NAME': 'mydb',
'USER': 'user#myserver',
'PASSWORD': 'password',
'HOST': 'myserver.database.windows.net',
'PORT': '',
'OPTIONS': {
'driver': 'ODBC Driver 13 for SQL Server',
},
},
}
# set this to False if you want to turn off pyodbc's connection pooling
DATABASE_CONNECTION_POOLING = False
USER: String. Database user name in "user" (on-premise) or "user#server" (Azure SQL Database) format. If not given then MS Integrated Security will be used.
Reference: django-pyodbc-azure 2.1.0.0
For on-premise SQL server, the database configuration:
DATABASES = {
'default': {
'ENGINE': 'sql_server.pyodbc',
'HOST': '(LocalDB)\ProjectLocalDB',
'PORT': '',
'NAME': 'my_db',
'USER': 'my_user',
'PASSWORD': 'my_password',
'OPTIONS': {
'driver': 'ODBC Driver 13 for SQL Server',
},
},
}
Here are two tutorials, I think you can learn from them to check if you have missed something:
How to use Django with SQL Server LocalDB: This post has been
tested with Microsoft SQL Server 2017, Django 1.11.x and 2.x. The
pyodbc and django-pyodbc-azure packages will be used to connect
Django to SQL Server. The version of django-pyodbc-azure must match
your version of Django.
Django and MS SQL Server: The new python module/library is the django-pyodbc-azure which supports Django
2.0 and lower versions like Django 1.11.
Hope this helps.
My database and project work great using this database setting:
DATABASES = {
'default': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'NAME': 'myprojectdb',
'USER': 'myprojectuser',
'PASSWORD': 'my_secret_password',
'HOST': 'localhost',
'PORT': '5432',
'ATOMIC_REQUESTS': True
},
}
But I want to add a 'readonly' database entry for my readonly db user, like this, so that I can run django-sql-explorer:
DATABASES = {
'default': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'NAME': 'myprojectdb',
'USER': 'myprojectuser',
'PASSWORD': 'my_secret_password',
'HOST': 'localhost',
'PORT': '5432',
'ATOMIC_REQUESTS': True
},
'readonly': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'NAME': 'myprojectdb',
'USER': 'myprojectreadonly',
'PASSWORD': 'your_eyes_only_secret',
'HOST': 'localhost',
'PORT': '5432',
'ATOMIC_REQUESTS': True
}
}
And now django throws a couple different errors. If I try to do anything with migrations, I get:
django.db.utils.ProgrammingError: permission denied for relation django_migrations
If I try to runserver, I get:
"AUTH_USER_MODEL refers to model '%s' that has not been installed" % settings.AUTH_USER_MODEL
django.core.exceptions.ImproperlyConfigured: AUTH_USER_MODEL refers to model 'users.User' that has not been installed
It seems like when I add the second database setting, django is attempting to use that for migrations, running the server, etc, even though it's not 'default'
If I comment out the second entry, everything works great again.
Any recommendations on how to correct this?
Edit: If I change the settings to use the same username and password, everything works great, so it's not just an issue of django being confused on names. IE:
DATABASES = {
'default': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'NAME': 'myprojectdb',
'USER': 'myprojectuser',
'PASSWORD': 'my_secret_password',
'HOST': 'localhost',
'PORT': '5432',
'ATOMIC_REQUESTS': True
},
'readonly': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'NAME': 'myprojectdb',
'USER': 'myprojectuser',
'PASSWORD': 'my_secret_password',
'HOST': 'localhost',
'PORT': '5432',
'ATOMIC_REQUESTS': True
}
}
The two configurations shares the same database names 'NAME': 'myprojectdb'
So when you try to migrates dbname seems to conflicts so the applications is having an indecision on which to use The previous or the later
I got thid error:
(2013, 'Lost connection to MySQL server during query')
I have read that I can increase database timeout.
What do I do?
Settings.py:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'c9',
'USER': ddd,
'PASSWORD': '',
'HOST': ddd,
'PORT': '3306',
'ATOMIC_REQUESTS': True
},
'OPTIONS': {
'timeout': 99999999,
'net_read_timeout': 9999999
}
Database object declaration is not correct, OPTIONS should be declared inside default object
#settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'c9',
'USER': ddd,
'PASSWORD': '',
'HOST': ddd,
'PORT': '3306',
'ATOMIC_REQUESTS': True,
'OPTIONS':{
'timeout': 99999999,
'net_read_timeout': 9999999
},
}
}
The company I work at has a test server which houses all test data. I'm attempting to add some much needed unit tests that reference our Django database on the test server. The problem I'm having is the test database is being created instead of pointing to the database I've provided. I had tried setting the database if test in the system arguments like this:
if 'test' in sys.argv:
DATABASES = {
'default': { # VM Testing
'ENGINE': 'sql_server.pyodbc',
'NAME': 'x',
'USER': 'x',
'PASSWORD': "x",
'HOST': 'x.x.x.x', #
'PORT': '',
'OPTIONS': {
'driver': 'FreeTDS',
'dsn': 'mssql_staging_1',
'extra_params': 'TDS_VERSION=8.0',
'use_legacy_datetime': False
},
},
}
DEBUG = False
TEMPLATE_DEBUG = False
And while it makes it into the this if statement, the test database is still created when running python manage.py test. Any advice? And FWIW all my tests to this point are using DRF and its APITestCase class. Thanks!
EDIT:
I tried running
python manage.py test -k
But Django is still using the default test database. I threw in a set trace to check, no objects were found.
The terminal output was:
Using existing test database for alias 'default'...
Here is my updated updated settings:
DATABASES = {
'default': {
'ENGINE': 'sql_server.pyodbc',
'NAME': 'x',
'USER': 'x',
'PASSWORD': "x",
'HOST': 'x.x.x.x',
'PORT': '',
'OPTIONS': {
'driver': 'FreeTDS',
'dsn': 'mssql_staging_1',
'extra_params': 'TDS_VERSION=8.0',
'use_legacy_datetime': False
}
},
'replica': {
'ENGINE': 'sql_server.pyodbc',
'NAME': 'x',
'USER': 'x',
'PASSWORD': "x",
'HOST': 'x.x.x.xreplica',
'PORT': '',
'OPTIONS': {
'driver': 'FreeTDS',
'dsn': 'mssql_staging_1',
'extra_params': 'TDS_VERSION=8.0',
'use_legacy_datetime': False
},
'TEST': {
'MIRROR': 'default',
}
}
}
I was finally able to get my test runner working by doing the following:
I moved the test condition from my staging settings file to a testing settings file (called testing.py)
The database setup:
if 'test' in sys.argv:
# WILL NOT WORK WHEN IF IS MISSING
DATABASES = {
'default': { # VM Testing
'ENGINE': 'sql_server.pyodbc',
'NAME': 'x',
'USER': 'x',
'PASSWORD': "x",
'HOST': 'x.x.x.x',
'PORT': '',
'OPTIONS': {
'driver': 'FreeTDS',
'dsn': 'mssql_staging_1',
'extra_params': 'TDS_VERSION=8.0',
'use_legacy_datetime': False
},
'TEST': {
'MIRROR': 'default',
}
},
}
and ran my test with the following command:
python manage.py test --settings=Project.settings.testing -k