i have created 2 table, ie table1 and table2 i want to insert data in to both tables using django ORM , how can i achieve it
models.py
class Table1(models.Model):
name = models.CharField(max_length=20,null=True)
class Table2(models.Model):
name = models.CharField(max_length=20,null=True)
views.py
class Test(ListAPIView):
def get(self,request):
obj1 = Table1(name="jasir")
obj2 = Table2(name="shibin")
obj1.save()
obj2.save()
return Response(True)
im saving like this but i want to save it using single save() instance is there any possiblity
the equivalent sql query i found is
BEGIN TRANSACTION
INSERT INTO Table1 (name) VALUES ('jasir')
INSERT INTO Table2 (name) VALUES ('shibin')
COMMIT TRANSACTION
how to do the same with django ORM
Try making the saves atomic like this:
with django.db.transaction.atomic():
obj1.save()
obj2.save()
you can use Django's transcation.atomic context-manager to do that
Refer to:
https://docs.djangoproject.com/en/2.2/topics/db/transactions/#django.db.transaction.atomic
with transaction.atomic():
# This code executes inside a transaction.
obj1 = Table1(name="jasir")
obj2 = Table2(name="shibin")
obj1.save()
obj2.save()
Related
I am using Django amdin for one of my data models. I want to display customized values on admin UI for each model.
On db, the result of a single query runs as multiple queries on django admin, one for each row
I am trying to avoid that.
Here are my models:
class words(models.Model):
word_id=models.AutoField(primary_key=True)
word=models.CharField(max_length=200,unique=True)
def __unicode__(self):
return '%s - %s' % (self.word,self.word_id)
class meanings(models.Model):
id=models.AutoField(primary_key=True)
word_id=models.ForeignKey(words,on_delete=models.CASCADE,db_column='word_id')
meaning=models.CharField(max_length=200)
def __unicode__(self):
return '%s %s %d ' % ( self.spelling_id.spelling,self.meaning,self.id)
For the second model, while loading the page, for each row I saw there are 2 queries running one on words table and other on meanings table. (from debug toolbar)
I tried avoiding that by using the below option.
models.py:
class meanings(models.Model):
meaning_id=models.AutoField(primary_key=True)
word_id=models.ForeignKey(words,on_delete=models.CASCADE,db_column='word_id')
meaning=models.CharField(max_length=200)
admin.py:
def modified_output(self):
cursor = connection.cursor()
cursor.execute("select word,meaning,id from meanings a,words b where a.word_id=b.word_id and meaning_id= "+str(self.id))
row = dictfetchall(cursor)
a=unicode(row[0]['word'])
b=unicode(row[0]['meaning'])
d=(row[0]['id'])
return '%s %s %d ' % ( a,b,d)
meanings.add_to_class("__str__", modified_output)
Now for each row there is only 1 query running. But as the dependency on models have more than 2 tables in join of a query, it will still consume time. So my question is instead of running 1 query for each row, can we have the query result displayed directly for each page.
for example result of the following query on a page:
select * from table ;
instead of
select * from table when id=1;
select * from table when id=2;
.
.
.
Any help is greatly appreciated.Thanks
You should use the list_select_related option on the ModelAdmin to tell Django to do a JOIN query.
class MeaningAdmin(admin.ModelAdmin):
list_select_related = ('word_id',)
(Note, you really shouldn't call your FK fields things like word_id. The field gives access to an actual instance of Word, so it should just be called word; the underlying db column will automatically be called word_id.)
I am trying to access pre-created MySQL View in the database via. peewee treating it as a table [peewee.model], however I am still prompted with Operational Error 1054 unknown column.
Does PeeWee Supports interactions with database view ?
Peewee has been able to query against views when I've tried it, but while typing up a simple proof-of-concept I ran into two potential gotcha's.
First, the code:
from peewee import *
db = SqliteDatabase(':memory:')
class Foo(Model):
name = TextField()
class Meta: database = db
db.create_tables([Foo])
for name in ('huey', 'mickey', 'zaizee'):
Foo.create(name=name)
OK -- nothing exciting, just loaded three names into a table. Then I made a view that corresponds to the upper-case conversion of the name:
db.execute_sql('CREATE VIEW foo_view AS SELECT UPPER(name) FROM foo')
I then tried the following, which failed:
class FooView(Foo):
class Meta:
db_table = 'foo_view'
print [fv.name for fv in FooView.select()]
Then I ran into the first issue.
When I subclassed "Foo", I brought along a primary key column named "id". Since I used a bare select() (FooView.select()), peewee assumed i wasnted both the "id" and the "name". Since the view has no "id", I got an error.
I tried again, specifying only the name:
print [fv.name for fv in FooView.select(FooView.name)]
This also failed.
The reason this second query fails can be found by looking at the cursor description on a bare select:
curs = db.execute_sql('select * from foo_view')
print curs.description[0][0] # Print the first column's name.
# prints UPPER(name)
SQLite named the view's column "UPPER(name)". To fix this, I redefined the view:
db.execute_sql('CREATE VIEW foo_view AS SELECT UPPER(name) AS name FROM foo')
Now, when I query the view it works just fine:
print [x.name for x in FooView.select(FooView.name)]
# prints ['HUEY', 'MICKEY', 'ZAIZEE']
Hope that helps.
I have code that works for getting models and fields from a Django database. However, it only works on the default database.
This function wants a database name, and I'd like to get the tables and fields for that database.
def browse_datasource(request, dbname):
table_info = []
# This is what I'd /like/ to be able to do, but it doesn't work:
# tables = connections[dbname].introspection.table_names()
tables = connection.introspection.table_names()
found_models = connection.introspection.installed_models(tables)
for model in found_models:
tablemeta = model._meta
columns = [field.column for field in model._meta.fields]
table_info.append([model.__name__, columns])
How can I perform introspection on the non-default databases? Is there a correct way to get connection.introspection for a database with the name "example", for example?
I found the solution. The trick is getting the database connection from the connections list, then getting a cursor and passing that to introspection.table_names, like so:
table_info = []
conn = connections[dbname]
cursor = conn.cursor()
tables = conn.introspection.table_names(cursor)
found_models = conn.introspection.installed_models(tables)
for model in found_models:
tablemeta = model._meta
I'm switching from PHP to Django/Python, and one thing I don't really like about django so far is the ORM. When inserting new rows, it's fine, but when I want to SELECT something more specific, I find that the ORM is more troublesome than pure SQL, specially since I already know SQL quite well.
So, can I write pure SQL in Django, or I am forced to use the ORM?
If it's possible, examples on how to use SQL in django would be very welcome.
Yes! You can.
https://docs.djangoproject.com/en/1.7/topics/db/sql/
From Django's awesome documentation;
There are two ways;
using a manager method raw()
https://docs.djangoproject.com/en/1.7/topics/db/sql/#performing-raw-queries
class Person(models.Model):
first_name = models.CharField(...)
last_name = models.CharField(...)
birth_date = models.DateField(...)
You could then execute custom SQL like so:
>>> for p in Person.objects.raw('SELECT * FROM myapp_person'):
... print(p)
John Smith
Jane Jones
Use the following method to pass parameters.
>>> lname = 'Doe'
>>> Person.objects.raw('SELECT * FROM myapp_person WHERE last_name = %s', [lname])
Executing custom SQL directly.
https://docs.djangoproject.com/en/1.7/topics/db/sql/#executing-custom-sql-directly
from django.db import connection
def my_custom_sql(self):
cursor = connection.cursor()
cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz])
cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
row = cursor.fetchone()
return row
yes, it is. Suppose you have a model like this:
class Foo(models.Model):
bar = models.CharField('bar', max_length=32)
you could write
Foo.objects.raw("SELECT bar from appname__foo LIMIT 5;")
or whatever SQL you like. the key is to use models.Model.objects.raw method.
It is up to you to make sure the query returns Foo objects though
Busy playing with django, but one thing seems to be tripping me up is following a foreign key relationship. Now, I have a ton of experience in writing SQL, so i could prob. return the result if the ORM was not there.
Basically this is the SQL query i want returned
Select
table1.id
table1.text
table1.user
table2.user_name
table2.url
from table1, table2
where table1.user_id = table2.id
My model classes have been defined as:
class Table1(models.Model):
#other fields
text = models.TextField()
user = models.ForeignKey('table2')
class Table2(models.Model):
# other fields
user_name = models.CharField(max_length=50)
url = models.URLField(blank=True, null=True)
I have been through the documentation and reference for querysets, models and views on the django website. But its still not clear on how to do this.
I have also setup the url with a generic list view, but would like to access the user_name field from the second table in the template. I tried select_related in urls.py and also via the shell but it does not seem to work. See examples below.
config in urls
url(r'^$','django.views.generic.list_detail.object_list', { 'queryset': Table1.objects.select_related() }),
At the shell
>>> a = Table1.objects.select_related().get(id=1)
>>> a.id
1
>>> a.user_name
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'Table1' object has no attribute 'user_name'
So basically,
What am i doing wrong?
Am i missing something?
What's the best way to pass fields from two tables in the same queryset to your template (So fields from both tables can be accessed)
Can this be done with generic views?
Something like this should work:
u = Table1.objects.get(id=1)
print u.id
print u.user.user_name
If you want to follow a foreign key, you must do it explicitly. You don't get an automatic join, when you retrieve an object from Table1. You will only get an object from Table2, when you access a foreign key field, which is user in this example
select_related() do not add second table result directly to the query, it just "Loads" them, insead of giving to you lazily. You should only use it, when you are sure it can boost your site performance. To get second table you need to write
a.user.username
In Django to get related table you need to follow them through foreign-keys that you have designed. Query itself do not directly translate to SQL query, because it is "lazy". It will execute only SQL that you need and only when you need.
If you have select_related SQL would have been executed at the moment when you do original query for a. But if you didn't have select_related then it would load DB only when you actually execute a.user.username.