Different databases for forms and authentification in django? - mysql

Is it possible to use one database for user authentifications in django and another database for working with django-forms? I work with non-relational data structures and feel comfortable with mongodb forms, but I unable to authorize my users, using mongodb. All posts describing mongodb-authentification with django referer to deprecated modules of mongoengine, which is no longer support django. So I decide to use mysql for user authentification and mongodb as main database, but cannot find information about defining special database for user authorization.
UPD:
I add mysql to setings:
DATABASES = {
'default': {
'ENGINE' : 'django.db.backends.dummy',
'NAME' : 'my_database'
},
'users': {
'NAME': 'my_users',
'ENGINE': 'django.db.backends.mysql',
'USER': 'django'
}
}
Migrate:
python3 manage.py migrate --database=users
It return:
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying sessions.0001_initial... OK
Then I tried to create a user:
set DJANGO_SETTINGS_MODULE=my_site.settings
,
>>> import django
>>> django.setup()
>>> from django.contrib.auth.models import User
>>> user = User.objects.create_user('john', 'lennon#thebeatles.com', 'johnpassword')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.5/dist-packages/django/contrib/auth/models.py", line 159, in create_user
return self._create_user(username, email, password, **extra_fields)
File "/usr/local/lib/python3.5/dist-packages/django/contrib/auth/models.py", line 153, in _create_user
user.save(using=self._db)
File "/usr/local/lib/python3.5/dist-packages/django/contrib/auth/base_user.py", line 80, in save
super(AbstractBaseUser, self).save(*args, **kwargs)
File "/usr/local/lib/python3.5/dist-packages/django/db/models/base.py", line 807, in save
force_update=force_update, update_fields=update_fields)
File "/usr/local/lib/python3.5/dist-packages/django/db/models/base.py", line 834, in save_base
with transaction.atomic(using=using, savepoint=False):
File "/usr/local/lib/python3.5/dist-packages/django/db/transaction.py", line 158, in __enter__
if not connection.get_autocommit():
File "/usr/local/lib/python3.5/dist-packages/django/db/backends/base/base.py", line 385, in get_autocommit
self.ensure_connection()
File "/usr/local/lib/python3.5/dist-packages/django/db/backends/dummy/base.py", line 20, in complain
raise ImproperlyConfigured("settings.DATABASES is improperly configured. "
django.core.exceptions.ImproperlyConfigured: settings.DATABASES is improperly configured. Please supply the ENGINE value. Check settings documentation for more details.
>>>
Guys, please, advise me, what was the wrong?
UPD2:
Add a router to settings.py:
class AuthRouter(object):
"""
A router to control all database operations on models in the
auth application.
"""
def db_for_read(self, model, **hints):
"""
Attempts to read auth models go to auth_db.
"""
if model._meta.app_label == 'auth':
return 'users'
return 'default'
def db_for_write(self, model, **hints):
"""
Attempts to write auth models go to auth_db.
"""
if model._meta.app_label == 'auth':
return 'users'
return 'default'
def allow_relation(self, obj1, obj2, **hints):
"""
Allow relations if a model in the auth app is involved.
"""
if obj1._meta.app_label == 'auth' or \
obj2._meta.app_label == 'auth':
return True
return False
def allow_migrate(self, db, app_label, model_name=None, **hints):
"""
Make sure the auth app only appears in the 'auth_db'
database.
"""
return db == 'auth_db'
DATABASE_ROUTERS = [AuthRouter]
Now i have enother error, when create user:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.5/dist-packages/django/contrib/auth/models.py", line 159, in create_user
return self._create_user(username, email, password, **extra_fields)
File "/usr/local/lib/python3.5/dist-packages/django/contrib/auth/models.py", line 153, in _create_user
user.save(using=self._db)
File "/usr/local/lib/python3.5/dist-packages/django/contrib/auth/base_user.py", line 80, in save
super(AbstractBaseUser, self).save(*args, **kwargs)
File "/usr/local/lib/python3.5/dist-packages/django/db/models/base.py", line 766, in save
using = using or router.db_for_write(self.__class__, instance=self)
File "/usr/local/lib/python3.5/dist-packages/django/db/utils.py", line 267, in _route_db
chosen_db = method(model, **hints)
TypeError: db_for_write() missing 1 required positional argument: 'model'
What's wrong in my router? I copied it from oficial docs.

Related

create an other table during tests manually in django webapp

I'm creating some tests in my django web app with selenium.
Django create a test database with all tables.
In my case however I have a model Users.
I want that django create also users table when I run this command in terminal
python3.9 manage.py test -v3
This command goes in error:
Running post-migrate handlers for application contenttypes
Adding content type 'contenttypes | contenttype'
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Running post-migrate handlers for application sessions
Adding content type 'sessions | session'
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Running post-migrate handlers for application pygiustizia
Adding content type 'pygiustizia | member'
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
System check identified no issues (0 silenced).
test_login (pygiustizia.tests.test_views_topics.ViewsTopicsTestCase) ... nel costruttore model Users
ERROR
======================================================================
ERROR: test_login (pygiustizia.tests.test_views_topics.ViewsTopicsTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/nicola/.local/lib/python3.9/site-packages/django/db/backends/utils.py", line 89, in _execute
return self.cursor.execute(sql, params)
File "/home/nicola/.local/lib/python3.9/site-packages/django/db/backends/mysql/base.py", line 75, in execute
return self.cursor.execute(query, args)
File "/home/nicola/.local/lib/python3.9/site-packages/pymysql/cursors.py", line 148, in execute
result = self._query(query)
File "/home/nicola/.local/lib/python3.9/site-packages/pymysql/cursors.py", line 310, in _query
conn.query(q)
File "/home/nicola/.local/lib/python3.9/site-packages/pymysql/connections.py", line 548, in query
self._affected_rows = self._read_query_result(unbuffered=unbuffered)
File "/home/nicola/.local/lib/python3.9/site-packages/pymysql/connections.py", line 775, in _read_query_result
result.read()
File "/home/nicola/.local/lib/python3.9/site-packages/pymysql/connections.py", line 1156, in read
first_packet = self.connection._read_packet()
File "/home/nicola/.local/lib/python3.9/site-packages/pymysql/connections.py", line 725, in _read_packet
packet.raise_for_error()
File "/home/nicola/.local/lib/python3.9/site-packages/pymysql/protocol.py", line 221, in raise_for_error
err.raise_mysql_exception(self._data)
File "/home/nicola/.local/lib/python3.9/site-packages/pymysql/err.py", line 143, in raise_mysql_exception
raise errorclass(errno, errval)
pymysql.err.ProgrammingError: (1146, "Table 'test_civiledb.users' doesn't exist")
EDIT
I access to the table users that I want create manually for test by this model.
from django.db import models
from django.db import connection
import pymysql
class Users(models.Model):
firstname=models.CharField(max_length=100)
lastname=models.CharField(max_length=100)
username=models.CharField(max_length=50)
password=models.CharField(max_length=255)
admin=models.IntegerField()
createdAt=models.DateTimeField(db_column="created_at")
def __init__(self,*args, **kwargs):
super().__init__(*args, **kwargs)
print("nel costruttore model Users")
def getAdmin(self):
return self.admin
class Meta:
db_table = 'users'
def getUser(self,username):
cursor = connection.cursor()
cursor.execute('''SELECT id,
username,
password,
admin,
firstname,
lastname,
created_at
FROM users
WHERE username = %s''',[username])
result = cursor.fetchone()
return result
def setPassword(self,userId,password):
cursor = connection.cursor()
try:
cursor.execute('''UPDATE users
SET password = %s
WHERE id = %s''',[password,userId])
connection.commit()
except Exception as e:
print(e)
connection.rollback()
return False
finally:
connection.close()
return True
A solution is to create "sql create" schema run it in testcase in setUp and drop it on tearDown.
I think the concept you are looking for here are unmanaged models. By setting the appropriate Meta option you can tell Django that it shouldn't handle the table lifecycle for you.
To answer your question, using SchemaEditor on test setup and teardown seems like a particularly clean way to achieve what you are looking for.

CustomUser on separate database issues

I want to use the users from a legacy database but keep everything else on the 'default' database.
The main issue I have atm is that I can't get the database router to properly forward queries to the appropriate database. Namely when I run the migrations 2 times, the second time I get an error
~> DJANGO_SETTINGS_MODULE=settings python manage.py makemigrations
Migrations for 'myapp':
myapp/migrations/0001_initial.py
- Create model CustomUser
~> DJANGO_SETTINGS_MODULE=settings python manage.py makemigrations
Traceback (most recent call last):
File "manage.py", line 21, in <module>
main()
File "manage.py", line 17, in main
execute_from_command_line(sys.argv)
File "/home/manos/workspace/umed/common/oauth2_test/.env/lib/python3.7/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
utility.execute()
File "/home/manos/workspace/umed/common/oauth2_test/.env/lib/python3.7/site-packages/django/core/management/__init__.py", line 395, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/manos/workspace/umed/common/oauth2_test/.env/lib/python3.7/site-packages/django/core/management/base.py", line 328, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/manos/workspace/umed/common/oauth2_test/.env/lib/python3.7/site-packages/django/core/management/base.py", line 369, in execute
output = self.handle(*args, **options)
File "/home/manos/workspace/umed/common/oauth2_test/.env/lib/python3.7/site-packages/django/core/management/base.py", line 83, in wrapped
res = handle_func(*args, **kwargs)
File "/home/manos/workspace/umed/common/oauth2_test/.env/lib/python3.7/site-packages/django/core/management/commands/makemigrations.py", line 101, in handle
loader.check_consistent_history(connection)
File "/home/manos/workspace/umed/common/oauth2_test/.env/lib/python3.7/site-packages/django/db/migrations/loader.py", line 299, in check_consistent_history
connection.alias,
django.db.migrations.exceptions.InconsistentMigrationHistory: Migration admin.0001_initial is applied before its dependency myapp.0001_initial on database 'auth_db'.
So I assume it tries to run the admin stuff inside the auth_db instead of default database. But I can't really figure out what I'm doing wrong since the routing seems correct.
Simplified code below
models.py
class CustomUser(AbstractUser):
password = models.CharField(max_length=128)
username = models.CharField(unique=True, max_length=32)
class Meta:
managed = False
db_table = 'myauthdb_user'
objects = UserManager()
db.py
class AuthRouter:
""" Forwards queries for users models to the auth database. """
def db_for_read(self, model, **hints):
if model.__name__ == 'CustomUser':
return 'auth_db'
return None
settings.py
DATABASE_ROUTERS = ['db.AuthRouter']
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': join(BASE_DIR, 'db.app'),
},
'auth_db': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'postgres',
'USER': 'postgres',
'PASSWORD': 'postgres',
'HOST': 'localhost',
},
}
I can use the ORM just fine e.g. CustomUser.objects.all(). But the migration issue is a huge problem. A naive solution is to disable the admin but I feel the underlying problem is still there.

Multiple errors while connecting to a database - python3.7

whenever I execute the following mysqlclient commands in python(3.7.4), a bunch of errors show up.
import MySQLdb
import mysql.connector
db = MySQLdb.connect(host='localhost',
port='3306',
database='py_test',
user='arnav',
password='1234')
db_cur = db.cursor()
db_cur.execute('insert into pass values ( \'arnav\', \'0000\' )')
These are the errors and I can't seem to find what the problem is. And my server is running just fine.
errors :
Traceback (most recent call last):
File "C:\Users\arnav\Desktop\python programs\sql.py", line 8, in <module>
password='1234')
File "C:\Users\arnav\AppData\Local\Programs\Python\Python37-32\lib\site-
packages\MySQLdb\__init__.py", line 84, in Connect
return Connection(*args, **kwargs)
File "C:\Users\arnav\AppData\Local\Programs\Python\Python37-32\lib\site-
packages\MySQLdb\connections.py", line 166, in __init__
super(Connection, self).__init__(*args, **kwargs2)
TypeError: an integer is required (got type str)
I have used mysql.connector in the past multiple times and it works perfectly fine, but I need to use mysqlclient for my project. So, please help.
I just used an f-string and it worked.

Airflow: Cannot assign requested address error while using emailoperator

Unable to receive email on task failure or even using EmailOperator
Hi Guys,
I am unable to receive email from my box even after adding required parameters to send one.
Below is how my default args looks like --
default_args = {
'owner': 'phonrao',
'depends_on_past': False,
#'start_date': datetime(2019, 3, 28),
'start_date': airflow.utils.dates.days_ago(2),
'email': ['phonrao#gmail.com'],
'email_on_failure': True,
'email_on_retry': True,
'retries': 1,
'retry_delay': timedelta(minutes=5),
#'on_failure_callback': report_failure,
#'end_date': datetime(2020,4 ,1),
#'schedule_interval': '#hourly',
}
I have few HttpsOperator task in between -- those are working good and are a success, but they do not send email on error(I purposely tried to introduce an error to check if they send any email). Below is an example of my task.
t1 = SimpleHttpOperator(
task_id='t1',
http_conn_id='http_waterfall',
endpoint='/update_data',
method='POST',
headers={"Content-Type":"application/json"},
xcom_push=True,
log_response=True,
dag=dag,
)
and this is my EmailOperator task
t2 = EmailOperator(
dag=dag,
task_id="send_email",
to='phonrao#gmail.com',
subject='Success',
html_content="<h3>Success</h3>"
)
t2 >> t1
Below is the error from Logs:
[2019-04-02 15:28:21,305] {{base_task_runner.py:101}} INFO - Job 845: Subtask send_email [2019-04-02 15:28:21,305] {{cli.py:520}} INFO - Running <TaskInstance: schedulerDAG.send_email 2019-04-02T15:23:08.896589+00:00 [running]> on host a47cd79aa987
[2019-04-02 15:28:21,343] {{logging_mixin.py:95}} INFO - [2019-04-02 15:28:21,343] {{configuration.py:255}} WARNING - section/key [smtp/smtp_user] not found in config
[2019-04-02 15:28:21,343] {{models.py:1788}} ERROR - [Errno 99] Cannot assign requested address
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/airflow/models.py", line 1657, in _run_raw_task
result = task_copy.execute(context=context)
File "/usr/local/lib/python3.6/site-packages/airflow/operators/email_operator.py", line 78, in execute
mime_subtype=self.mime_subtype, mime_charset=self.mime_charset)
File "/usr/local/lib/python3.6/site-packages/airflow/utils/email.py", line 55, in send_email
mime_subtype=mime_subtype, mime_charset=mime_charset, **kwargs)
File "/usr/local/lib/python3.6/site-packages/airflow/utils/email.py", line 101, in send_email_smtp
send_MIME_email(smtp_mail_from, recipients, msg, dryrun)
File "/usr/local/lib/python3.6/site-packages/airflow/utils/email.py", line 121, in send_MIME_email
s = smtplib.SMTP_SSL(SMTP_HOST, SMTP_PORT) if SMTP_SSL else smtplib.SMTP(SMTP_HOST, SMTP_PORT)
File "/usr/local/lib/python3.6/smtplib.py", line 251, in __init__
(code, msg) = self.connect(host, port)
File "/usr/local/lib/python3.6/smtplib.py", line 336, in connect
self.sock = self._get_socket(host, port, self.timeout)
File "/usr/local/lib/python3.6/smtplib.py", line 307, in _get_socket
self.source_address)
File "/usr/local/lib/python3.6/socket.py", line 724, in create_connection
raise err
File "/usr/local/lib/python3.6/socket.py", line 713, in create_connection
sock.connect(sa)
OSError: [Errno 99] Cannot assign requested address
[2019-04-02 15:28:21,351] {{models.py:1817}} INFO - All retries failed; marking task as FAILED
Below is my airflow.cfg
[email]
email_backend = airflow.utils.email.send_email_smtp
[smtp]
# If you want airflow to send emails on retries, failure, and you want to use
# the airflow.utils.email.send_email_smtp function, you have to configure an
# smtp server here
smtp_host = localhost
smtp_starttls = True
smtp_ssl = False
# Uncomment and set the user/pass settings if you want to use SMTP AUTH
# smtp_user = airflow
# smtp_password = airflow
smtp_port = 25
smtp_mail_from = airflow#example.com
Has anyone encounter this issue and any suggestions on how do I resolve this?
If your airflow running on Kubernetes (installed by helm chart), you should take a look in "airflow-worker-0" pod, and make sure the environment variable of SMTP_HOST or SMTP_USER ... available in the config. Simply debugging, access to the container of airflow-worker and then run python, then trying these commands to make sure it works correctly.
import airflow
airflow.utils.email.send_email('example#gmail.com', 'Airflow TEST HERE', 'This is airflow status success')
I have the same issues, by resolving the environment variable of SMTP. Now it works.

django-balanced - Database Error

I'm trying to install the django-balanced app in my project and I'm getting an error.
I did the following as the readme file says:
#Add to settings
import os
BALANCED = {
'API_KEY': os.environ.get('BALANCED_API_KEY'),
}
INSTALLED_APPS = (
...
'django.contrib.admin', # if you want to use the admin interface
'django_balanced',
...
)
#ran the following on my project root folder
BALANCED_API_KEY=YOUR_API_KEY django-admin.py syncdb #replacing the YOUR_API_KEY with my key
When I do this, I get the following error:
Traceback (most recent call last):
File "/usr/local/bin/django-admin.py", line 5, in <module>
management.execute_from_command_line()
File "/Library/Python/2.7/site-packages/django/core/management/__init__.py", line 453, in execute_from_command_line
utility.execute()
File "/Library/Python/2.7/site-packages/django/core/management/__init__.py", line 392, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/Library/Python/2.7/site-packages/django/core/management/__init__.py", line 272, in fetch_command
klass = load_command_class(app_name, subcommand)
File "/Library/Python/2.7/site-packages/django/core/management/__init__.py", line 77, in load_command_class
module = import_module('%s.management.commands.%s' % (app_name, name))
File "/Library/Python/2.7/site-packages/django/utils/importlib.py", line 35, in import_module
__import__(name)
File "/Library/Python/2.7/site-packages/django/core/management/commands/syncdb.py", line 8, in <module>
from django.core.management.sql import custom_sql_for_model, emit_post_sync_signal
File "/Library/Python/2.7/site-packages/django/core/management/sql.py", line 9, in <module>
from django.db import models
File "/Library/Python/2.7/site-packages/django/db/__init__.py", line 11, in <module>
if settings.DATABASES and DEFAULT_DB_ALIAS not in settings.DATABASES:
File "/Library/Python/2.7/site-packages/django/conf/__init__.py", line 53, in __getattr__
self._setup(name)
File "/Library/Python/2.7/site-packages/django/conf/__init__.py", line 46, in _setup
% (desc, ENVIRONMENT_VARIABLE))
django.core.exceptions.ImproperlyConfigured: Requested setting DATABASES, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
When I do the python manage.py syncdb, I get no errors with the database. I might be missing something in the database setting that the readme file does not mention. Thanks in advance
here is my database settings:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
'NAME': 'payload', # Or path to database file if using sqlite3.
'USER': 'root', # Not used with sqlite3.
'PASSWORD': 'pass123', # Not used with sqlite3.
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '', # Set to empty string for default. Not used with sqlite3.
}
}
You can also type the following command
BALANCED_API_KEY=YOUR_API_KEY python manage.py syncdb
You need to set the DJANGO_SETTINGS_MODULE:
You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings