How can we sync different databases and application in django - python

How can we access other database tables into django application database. Here 'default' database is main application and 'cl_db' is other application which is developed in asp.net but using same database server here how can we sync 'cl_db' database into 'default' database.
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'fail_over',
'USER': 'SomeUser',
'PASSWORD': 'SomePassword',
'HOST': '127.0.0.1',
'PORT': '',
},
'cl_db': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'cl_dev',
'USER': 'SomeUser',
'PASSWORD': 'SomePassword',
'HOST': '127.0.0.1',
'PORT': '',
},
}
DATABASE_ROUTERS = ['app.dbrouters.AuthRounter']
class AuthRouter:
"""
A router to control all database operations on models in the
auth and contenttypes applications.
"""
route_app_labels = {'auth', 'contenttypes'}
def db_for_read(self, model, **hints):
"""
Attempts to read auth and contenttypes models go to auth_db.
"""
if model._meta.app_label in self.route_app_labels:
return 'default'
return None
def db_for_write(self, model, **hints):
"""
Attempts to write auth and contenttypes models go to auth_db.
"""
if model._meta.app_label in self.route_app_labels:
return 'default'
return None
def allow_relation(self, obj1, obj2, **hints):
"""
Allow relations if a model in the auth or contenttypes apps is
involved.
"""
if (
obj1._meta.app_label in self.route_app_labels or
obj2._meta.app_label in self.route_app_labels
):
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
"""
Make sure the auth and contenttypes apps only appear in the
'auth_db' database.
"""
if app_label in self.route_app_labels:
return db == 'default'
return None
models.py
class usermaster(models.Model):
userid = models.AutoField(primary_key=True, unique=True)
class Meta:
app_label = 'user_master'

Related

Not Working the Migrationfrom Django to Postgres and MongoDb

I am a newcomer to MongoDB and currently attempting to establish a connection between MongoDB and Django. However, I have been successful in establishing a connection with Postgres, but I am facing difficulties in connecting to MongoDB. Although there are no errors occurring during the migration process, I am not seeing any migration on the MongoDB side.
Setting.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'base_app.apps.BaseAppConfig',
'document_app.apps.DocumentAppConfig',
]
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'HOST': os.environ.get('POSTGRES_HOST'),
'NAME': os.environ.get('POSTGRES_NAME'),
'USER': os.environ.get('POSTGRES_USER'),
'PASSWORD': os.environ.get('POSTGRES_PASSWORD'),
'PORT': os.environ.get('POSTGRES_PORT'),
},
"mongodb": {
"ENGINE": "djongo",
"NAME": os.environ.get('MONGO_DB_NAME'),
"CLIENT": {
"host": os.environ.get('MONGO_DB_HOST'),
"port": int(os.environ.get('MONGO_DB_PORT')),
# "username": os.environ.get('MONGO_DB_USERNAME'),
# "password": os.environ.get('MONGO_DB_PASSWORD'),
},
'TEST': {
'MIRROR': 'default',
},
}
}
DATABASE_ROUTERS = ['base_app.utils.routers.MyRouter', 'document_app.utils.routers.MyRouter']
base_app/model.py
class PostgresModel(models.Model):
# fields for Postgres database here
title = models.CharField(max_length=100)
content = models.TextField()
class Meta:
db_table = 'postgres_model'
app_label = 'base_app'
managed = True
abstract = False
document_app\models.py
from djongo import models as djmodels
from django.db import models
class MongoDBModel(djmodels.Model):
# fields for MongoDB database here
name = models.CharField(max_length=100)
age = models.IntegerField()
address = models.CharField(max_length=200)
class Meta:
db_table = 'mongodb_model'
app_label = 'document_app'
managed = True
abstract = False
class MongoDBDocument(djmodels.Model):
# fields for MongoDB database here
name = models.CharField(max_length=100)
age = models.IntegerField()
address = models.CharField(max_length=200)
class Meta:
db_table = 'mongodb_model_document'
app_label = 'document_app'
managed = True
abstract = False
base_app.utils.routers.MyRouter
class MyRouter:
"""
A router to control all database operations on models in the
myapp application.
"""
def db_for_read(self, model, **hints):
"""
Attempts to read models go to the default PostgreSQL database.
"""
if model._meta.app_label == 'base_app':
return 'default'
return None
def db_for_write(self, model, **hints):
"""
Attempts to write models go to the MongoDB database.
"""
if model._meta.app_label == 'base_app':
return 'default'
return None
def allow_relation(self, obj1, obj2, **hints):
"""
Allow relations only between objects that are both in the MongoDB database.
"""
if obj1._meta.app_label == 'base_app' and obj2._meta.app_label == 'base_app':
if obj1._state.db == 'default' and obj2._state.db == 'default':
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
"""
Ensure that all models are created in the default PostgreSQL database.
"""
if app_label == 'base_app':
return db == 'default'
return None
'document_app.utils.routers.MyRouter'
class MyRouter:
"""
A router to control all database operations on models in the
myapp application.
"""
def db_for_read(self, model, **hints):
"""
Attempts to read models go to the default PostgreSQL database.
"""
if model._meta.app_label == 'document_app':
return 'mongodb'
return None
def db_for_write(self, model, **hints):
"""
Attempts to write models go to the MongoDB database.
"""
if model._meta.app_label == 'document_app':
return 'mongodb'
return None
def allow_relation(self, obj1, obj2, **hints):
"""
Allow relations only between objects that are both in the MongoDB database.
"""
if obj1._meta.app_label == 'document_app' and obj2._meta.app_label == 'document_app':
if obj1._state.db == 'mongodb' and obj2._state.db == 'mongodb':
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
"""
Ensure that all models are created in the default PostgreSQL database.
"""
if app_label == 'document_app':
return db == 'mongodb'
return None
Folder Structure
Requirement.txt
asgiref 3.6.0
Django 4.1.7
djangorestframework 3.14.0
pip 22.3.1
python-dotenv 0.21.1
pytz 2022.7.1
setuptools 65.5.0
sqlparse 0.4.3
tzdata 2022.7
I trust that the information provided is adequate. I am seeking your assistance in identifying the cause of the unsuccessful migration of MongoDB in Django. Your assistance would be greatly appreciated. Thank you in advance

Custom manager in Django MultiDB

I'am using MySQL and PostgreSQL in my Django project. Below are the settings:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mysql_db',
'USER': 'username',
'PASSWORD': 'password',
'HOST': 'hostname',
'PORT': '3306',
},
'postgres_db': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'pgsql_db',
'USER': 'username',
'PASSWORD': 'password',
'HOST': 'hostname',
'PORT': '5432',
}
}
And this is the sample model
from postgres_copy import CopyManager
class Items(models.Model):
class params:
db = "postgres_db"
sales_value = models.CharField(max_length=255, null=True, blank=True)
primary_email = models.CharField(max_length=255, null=True, blank=True)
objects = CopyManager()
I want to use Items.objects.all().to_csv('./path/to/csv) this ORM to export model data to CSV. I have used this before in exporting large dataset to csv.
But in this configuration it gives below error
psycopg2.errors.SyntaxError: syntax error at or near "."
LINE 1: COPY (SELECT `sales_item`.`id`, `sales_item`.`sales_value`,...
This seems to be an issue with multiDB.
If I run this ORM in single DB configuration, or even if I set default alias on PostgreSQL this works fine.
CopyManager seems to be getting default alias somehow which I have no idea about.
How can I run this ORM in current settings without any issues?
Any help would be appreciated.
Thanks in advance.
We use postgres and MariaDB in the same time in one project.
I can say - you dont need any additional data manager, in your case it can be:
from django.db.import models
class ItemsQuerySetManager(models.Manager):
def get_queryset(self, *args, **kwargs):
return super().get_queryset(*args, **kwargs).using("postgres_db")
class Items(models.Model):
sales_value = models.CharField(max_length=255, null=True, blank=True)
primary_email = models.CharField(max_length=255, null=True, blank=True)
objects = ItemsQuerySetManager()
more info here: https://docs.djangoproject.com/en/4.1/topics/db/multi-db/

Python Django - Read data from multiple databases

I have a Django app that works with multiple databases and I'm having an issue trying to read data specifically from (testdb2) database.
I do know that you can choose which database that you want to read data using keyword (Using) but that didn't work. The result is it's always tries to read data from (testdb).
Here is the code for database in (Settings.py):
DATABASES = {
'default': {
'NAME': 'testdb',
'ENGINE': 'django.db.backends.postgresql',
'USER': 'username',
'PASSWORD': 'password',
'HOST': 'host',
'PORT': 'port',
},
'users': {
'NAME': 'testdb2',
'ENGINE': 'sql_server.pyodbc',
'USER': 'username',
'PASSWORD': 'password',
'HOST': 'host',
'PORT': 'port',
'OPTIONS': {
'driver': 'ODBC Driver 13 for SQL Server',
},
},
}
Here is the code for (Views.py):
from rest_framework import viewsets
from .models import MyModel
from .serializers import MyModelSerializer
# Create your views here.
class MyModelView(viewsets.ModelViewSet):
queryset = MyModel.objects.using('users').all()
serializer_class = MyModelSerializer
Here is the code for (Models.py):
from django.db import models
from django.db import connection
# Create your models here.
class MyModel(models.Model):
columnName = models.IntegerField(db_column='columnName', primary_key=True)
columnEmail= models.IntegerField(db_column='columnEmail')
columnAddress= models.IntegerField(db_column='columnAddress')
columnPhone= models.IntegerField(db_column='columnPhone')
class Meta:
managed = False # Created from a view. Don't remove.
db_table = 'UserTable'
MyModel is based on a view that is created inside the database.
My question: How can I read data from the database (testdb2)
Thanks :D
I think viewset uses using method only in list. Because using method is only in queryset, so don't use viewset, or use a database router.
I recommend you database router. Check Database Router Doc
In addition to Yongjin Jo's opinion, ModelViewSet in DRF inherits CreateModelMixin. And it's create function.
class CreateModelMixin(object):
"""
Create a model instance.
"""
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
def perform_create(self, serializer):
serializer.save()
def get_success_headers(self, data):
try:
return {'Location': str(data[api_settings.URL_FIELD_NAME])}
except (TypeError, KeyError):
return {}
function create model instance by Serializer. So using method is not used.
You can override save method in Serializer. Or Use database router as Yongjin Jo said.

Django Unitest: Table doesn't exist

I created a simple test case like this:
from unittest import TestCase
import user_manager
class UserTest(TestCase):
def test_register(self):
email = "dung7#gmail.com"
password = "123456"
result, user = user_manager.setup_new_user(email, password)
self.assertEqual(result, CodeID.SUCCESS)
Then I run the testcase:
python manage.py test users
And here is the log:
Creating test database for alias 'default'...
/Users/admin/Projects/MyApp/venv/lib/python2.7/site-packages/django/db/backends/mysql/base.py:112: Warning: Table 'mysql.column_stats' doesn't exist
return self.cursor.execute(query, args)
Creating test database for alias 'myapp_log'...
.FE
======================================================================
ERROR: test_register (users.tests.UserTest)
----------------------------------------------------------------------
Traceback (most recent call last):
...
ProgrammingError: (1146, "Table 'test_myapp.user' doesn't exist")
So it created a test database but seem like it didn't create the tables. Here is my DATABASES setting:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': "myapp",
'USER': "root",
'PASSWORD': "",
'HOST': '127.0.0.1',
'PORT': '',
},
'myapp_log': {
'ENGINE': 'django.db.backends.mysql',
'NAME': "myapp_log",
'USER': "root",
'PASSWORD': "",
'HOST': '127.0.0.1',
'PORT': '',
},
}
And my model:
class User(BaseModel):
uid = models.IntegerField(primary_key=True)
email = models.CharField(max_length=200)
password = models.CharField(max_length=200)
create_time = models.IntegerField()
update_time = models.IntegerField()
status = models.IntegerField()
social_token = models.CharField(max_length=200)
social_app = models.IntegerField()
class Meta:
db_table = 'user'
Anyone know why the table 'user' is not created?
UPDATE:
user_manager from my testcase will do some query and add new record on table user.
And I thought when I run the testcase, Django will somehow read my models and create a test database with all the table from those models. Am I right about this?
So I found out I need to put my models.py in my users' folder and add 'users' into the INSTALLED_APPS setting. Now it worked.
Your test database needs to be different than your production database. Test databases are destroyed once the test cases are run. In your case the database was not created. You should go through this documentation for detailed information https://docs.djangoproject.com/en/1.10/topics/testing/overview/
Can you also add the snippet of your user_manager module

Make peewee admin work with flask security

I like both peewee and Flask security, and they both work well together, but I can't get the admin functionality of peewee to work. I am really not sure about how to do this, but I really want to use both together. I have tried a lot of things, but nothing seems to work.
My current code looks like this:
import datetime
from flask import Flask, abort, redirect, render_template, url_for, flash, request
from flask_peewee.auth import Auth, BaseUser
from flask_peewee.db import Database
from flask_peewee.admin import Admin, ModelAdmin
from flask_peewee.rest import RestAPI, UserAuthentication
from peewee import *
from flask.ext.security import *
# Create app
app = Flask(__name__)
app.config['DEBUG'] = True
app.config['SECRET_KEY'] = 'super-secret'
app.config['DATABASE'] = {
'name': 'ee.db',
'engine': 'peewee.SqliteDatabase',
}
# Create database connection object
db = Database(app)
class Role(db.Model, RoleMixin):
name = TextField(unique=True)
description = TextField(null=True)
class RoleAdmin(ModelAdmin):
columns = ('name', 'description')
class User(db.Model, UserMixin):
username = TextField()
password = TextField()
email = TextField()
role = ForeignKeyField(Role)
active = BooleanField(default=True)
confirmed_at = DateTimeField(null=True)
class UserAdmin(ModelAdmin):
columns = ('username', 'email', 'role', 'active', 'confirmed_at')
class UserRoles(db.Model):
user = ForeignKeyField(User, related_name='roles')
role = ForeignKeyField(Role, related_name='users')
name = property(lambda self: self.role.name)
description = property(lambda self: self.role.description)
class UserRolesAdmin(ModelAdmin):
columns = ('user', 'role', 'name', 'description')
class Note(db.Model):
user = ForeignKeyField(User, related_name='notes')
title = CharField()
message = TextField()
created = DateTimeField(default=datetime.datetime.now)
def __unicode__(self):
return '%s: %s %s' % (self.user.username, self.message, self.created)
class NoteAdmin(ModelAdmin):
columns = ("user", "message", "created")
foreign_key_lookups = {'user': 'username'}
class CustomAuth(Auth):
def get_user_model(self):
return User
def get_model_admin(self):
return UserAdmin
class CustomAdmin(Admin):
def check_user_permission(self, user):
if has_role(current_user).name == "admin":
return True
# Setup Flask-Security
user_datastore = PeeweeUserDatastore(db, User, Role, UserRoles)
security = Security(app, user_datastore)
#Setup Flask-Peewee admin
auth = CustomAuth(app, db)
admin = CustomAdmin(app, auth)
admin.register(Note, NoteAdmin)
admin.register(User, UserAdmin)
admin.setup()
#create a RestAPI container
api = RestAPI(app)
#register the Note model
api.register(Note)
api.setup()
#instantiate the user auth
user_auth = UserAuthentication(auth)
# Views
#app.route("/")
#login_required
def index():
messages = Note.select()
return render_template("base.html",
notes = messages,
username = current_user.username,
role = current_user.role.name
)
#app.route("/add", methods = ['post'])
#login_required
def add():
user = current_user
now = datetime.datetime.now()
Note.create(user = current_user.get_id(), title = request.form["title"], message = request.form["message"], created = now)
flash('New entry was successfully posted')
return redirect(url_for('index'))
#app.route("/delete/<id>")
#login_required
def delete(id):
note = Note.get(Note.id == id)
note.delete_instance()
flash('Entry was successfully removed')
return redirect(url_for('index'))
if __name__ == '__main__':
for Model in (Role, User, UserRoles):
Model.drop_table(fail_silently=True)
Model.create_table(fail_silently=True)
user_datastore.create_role(name="admin", description="admin")
user_datastore.create_user(username="Ben", email='hello', password='password', active=True, confirmed_at=datetime.datetime(1935,9,9,9,9), role=1)
user_datastore.add_role_to_user('hello', "admin")
Note.create_table(fail_silently=True)
app.run(port = 8080)
When I try to log in into the Peewee Admin, I get the following error: `AttributeError: 'User' object has no attribute 'check_password'
EDIT:
Full debug:
File "/anaconda/lib/python2.7/site-packages/flask_peewee/auth.py", line 170, in login
form.password.data,
File "/anaconda/lib/python2.7/site-packages/flask_peewee/auth.py", line 128, in authenticate
if not user.check_password(password):
AttributeError: 'User' object has no attribute 'check_password
I really do not understand why this raises an AttributeError. The password is registered, and the BaseUser class is imported (required for check_password). What am I doing wrong?
Your User class needs to implement the check_password and set_password methods, because Flask-Peewee calls those to authenticate requests and update models.
Flask-Peewee provides a class, BaseUser, with simple implementations you could mix in to User, but this probably isn't useful when you're also using Flask-Security. You'll need to implement the methods yourself in a way that they call into Flask-Security to compare and hash passwords, because the two projects' approaches to password hashing are different, and you're only saving one hash in the database.

Categories

Resources