Delete records from a collection of a specified DB - django

I am using mongoDB as my database, i am working on django projects and using mongoengine to connect with database. My question is if my default database in settings.py is DB1 and i want to delete all records of a collection which exists inside DB2 then how can i do this.
settings.py
import mongoengine
mongoengine.connect(
db= "DB1",
host='localhost',
)
models.py
class Resources(Document):
field1= fields.StringField(max_length=20)
field2 = fields.StringField(max_length=70)
field3 = fields.StringField(max_length=70)
field4 = fields.DictField()
meta = {'collection': 'resources', 'allow_inheritance': False, '_target_db': 'DB2'}
python shell
from .models import Resources
import mongoengine
mongoengine.connect('DB2', alias='ces')
ob = Resources()
ob.switch_db('ces')
ob.field1 = value
ob.field2 = value
ob.field3 = value
ob.save()
Now i have collection resources in DB2 and it has some records, i have tried Resources.objects.all().delete() but it is not deleting records form DB2 instead it deletes records from DB1 which is default database.

If each of your model is bound to 1 (and only 1) database, you can achieve what you want using connection alias and meta = {'db_alias': 'your_connectio_alias'} (docs)
See this post for an example

Related

Dynamically creating tables using SQLite and Django

I am given a task for a web application I’m developing currently. Currently, my code allow me to do the necessary saving to the existing tables, but I am unsure of how to do the following task. The task is to dynamically create tables as long as the 'save' button is pressed in my web application. I am using SQLite for my database.
Example: I have the field of 'name'. So the user types Test for the name field. Upon saving, this name is stored in an existing table and register under a id of 1. At the same time, I want to be able to create a new table with its own fields. This table will be named example_(id). So in this case it will be example_1.
I’m a beginner in Django and SQL so if anyone can guide/help me in any way, thank you!
Got the error of
views.py
#api_view(['GET'])
def selected_device(request,pk=None):
if pk != None:
devices = Device.objects.filter(pk=pk)
devicedetail = DeviceDetail.objects.filter(DD2DKEY=pk)
cursor = connection.cursor()
tablename= "dev_interface_" + str(pk)
cursor.execute(f"SELECT interface FROM {tablename} ")
righttable = cursor.fetchall()
devserializer = DeviceSerializers(devices, many=True)
devdserializer = DeviceDetailSerializers(devicedetail, many=True)
interfaces = []
for i in righttable:
interfaces.append(i[0])
for i in interfaces:
data =[{"interface": i}]
interserializer = InterfaceSerializers(data, many = True)
results = {
"device":devserializer.data,
"device_details" : devdserializer.data,
"interface":interserializer.data,
}
return Response(results)
In interfaces, I have the following ['G0/1', 'TenGigabitEthernet1/1/3', 'TenGigabitEthernet1/1/5', 'TenGigabitEthernet1/1/20', 'TenGigabitEthernet1/1/21', 'TenGigabitEthernet1/1/22', 'TenGigabitEthernet1/1/23', 'TenGigabitEthernet1/1/24', 'TenGigabitEthernet1/1/25', 'TenGigabitEthernet1/1/26']
I have mentioned in the comments that you can use database connection with raw SQL. Here is an example for you:
from django.db import connection
# Create a connection with your database
cursor = connection.cursor()
# Execute your raw SQL
cursor.execute("CREATE TABLE NameTable(name varchar(255));")
# Create database records
cursor.execute("INSERT INTO NameTable VALUES('ExampleName')")
# Fetch records from the database
cursor.execute("SELECT * FROM NameTable")
# Get the data from the database. fetchall() can be used if you would like to get multiple rows
name = cursor.fetchone()
# Manipulate data
# Don't forget the close database connection
cursor.close()
This is just a basic example about database connection in Django. Customize it depending on your needs. Here is the official documentation for raw SQL and database connections. Also keep in mind that what you are trying to do may not be the best practice or recommended.

Django fixture creation, ignoring relations between objects

I'm testing views in a django app. There are a lot of OneToMany and ManyToMany relations between models (users, departments, reports, etc.) It takes a lot of time upfilling certain fields like name, surname date of birth etc. while creating fixture which I dont use at all. How can I ignore them? Also what are the best practices while creating a fixture? Mine lools like this
class TestReportModel(TestCase):
allow_database_queries = True
#classmethod
def setUpTestData(cls):
cls.report_id = 99
cls.factory = RequestFactory()
cls.user_with_access = User.objects.create(username="user1", password="password")
cls.employee = Employee.objects.create(user=cls.user_with_access, fio="name1 surname1",
date_of_birth="2012-12-12")
cls.indicator = Indicator.objects.create(context_id=10, set_id=10)
cls.ife = IndicatorsForEmployees.objects.create(employee=cls.employee, indicator=cls.indicator)
cls.report = Report.objects.create(owner=cls.ife)
cls.report.id = cls.report_id
cls.report.save()
cls.user_with_no_access = User.objects.create(username="user_with_no_access", password="password")
cls.employee_with_no_access = Employee.objects.create(user=cls.user_with_no_access, fio="name2 surname2",
date_of_birth="2018-12-12")
It sounds like you need to specify a test database in your settings file, load a fixture with syncdb, then use the keepdb flag.
In your settings file, you can specify a test database name within databases.
https://docs.djangoproject.com/en/2.0/ref/settings/#std:setting-DATABASE-TEST
If this database is not found, it will be created when you run the tests. Once your fixture is created, you can use syncdb to load that db.
https://code.djangoproject.com/wiki/Fixtures#Fixtures
Then when you run your unit tests, pass --keepdb with it and the database will persist between tests.
https://docs.djangoproject.com/en/2.0/ref/django-admin/#cmdoption-test-keepdb

sqlalchemy : querying an existing table in the database

I understand how to create a table and query it using sqlalchemy. But what I am trying to do is different. I just want to query a table that already exists and which I did not create. What that means is I won't have a Python class defined for it in my code.
How do I query such a table ?
You can access an existing table using the following code.
For example if your table is users then:
from sqlalchemy.orm import Session
Base = automap_base()
Base.prepare(engine, reflect=True)
Users = Base.classes.users
session = Session(engine)
res = session.query(Users).first()

create django models from existing sqlite db

I am used in creating orm and leaving django responsible for creating the tables.But in a project I am involved I have to create a simple CRUD application a frontend for an existing database. The database was created by creating the tables manually. So I have two tables Table1 and Table2 which have a many to many relationship through Tables12. Tables12 looks like the table that django would normaly create using a ManyToManyField thus it has two fields the id's of the two models. So after using django's inspectdb, django successfully created the models according to the SQLite database. The many to many tables like Tables12 was created like the following(as stated above):
class Tables12(models.Model):
table1 = models.ForeignKey(Table1)
table2 = models.ForeignKey(Table2)
class Meta:
managed = False
db_table = "Tables12"
unique_together = (("table1_id", "table2_id"),)
Trying the following gives me an error:
>> table2 = Table2.objects.get(pk=1)
>>tables12 = Tables12.objects.filter(table2=table2)
>>tables12
OperationalError: no such column: Tables12.id
I am guessing Django's orm is expecting an id field in every models created. How can I bypass this behavior? Is there a way to edit the tables so as they look more like django's orm but behave as the existing db's tables? Like:
class Table1(models.Model):
#pre exsiting fields
table2 = models.ManyToManyField(Table2)
or
class Table2(models.Model):
#pre existing fields
table1 = models.ManyToManyField(Table1)
but without destroying database records and without creating tables from start.
You can remove the Tables12 model, and specify the db_table argument to a ManyToManyField:
class Table1(models.Model):
tables2 = models.ManyToManyField(Table2, db_table='Tables12')
You would still not be able to query the Tables12 model directly (it still exists and has an id field), but this would allow you to use the JOINs Django generates for a ManyToManyField:
table1 = Table1.objects.get(pk=1)
tables2 = table1.tables2.all()
This would still not allow you to use Django to write to the join table, but it allows you to use the data that's in it. If at all possible, I'd strongly recommend adding a primary key.

How to use Django forms ModelChoiceField with external database values

I am trying to use a ModelChoiceField to get the values populated from an external database.
I have added an additional database in my setting.py and have set up a externaldb.py file in my app as follows:
from django.db import connections
def Location():
rs = []
cursor = connections['mydb'].cursor()
cursor.execute("SELECT city FROM db.data_center WHERE removed is null;")
zones = cursor.fetchall()
for v in zones[::]:
rs.append(v)
The using python manage.py shell I can do this
>>>from platform.externaldb import Location
>>>print Location()
>>>[(u'India-01',), (u'Singapore-01',), (u'Europe-01',)]
So I am getting values but how to I get that to appear in a drop down box.. This is my forms.py
forms.py
from platform.externaldb import Location
zone = forms.ModelChoiceField(Location(), label='Zone')
But this doesn't work for me.. How do I do this so the 3 values appears in the ModelChoiceField drop down list?
Thanks - Oli
You could make use of the ChoiceField form field rather then the ModelChoiceField. The problem with using a ModelChoiceField is that it expects a QuerySet. The ChoiceField allows you to add items via a List instead.
locations = forms.ChoiceField(choices=Locations(), label="Zone")
EDIT
Previously, I had used the ModelChoiceField:
locations = forms.ModelChoiceField(queryset=Location.objects.all(), label="Zone")
which will work as long as Location is a Model (which I wasn't sure of based on your code)