Join Django model from other database - python

The situation is as follows in the Django implementation:
Two different database;
Two models with different information
Order number is relation between these models.
I would like to join these models together to get related information. Example
class CurtainOrder(models.Model):
order = models.ForeignKey('curtainconfig.Order', related_name='curtains')
order_number = models.IntegerField(unique=True)
order_type = models.CharField(max_length=50)
class ProductionOrder(models.Model):
id = models.IntegerField(primary_key=True, db_column=u'lOrder_id')
order_number = models.IntegerField(db_column=u'nOrderNumber')
status = models.TextField(db_column=u'cExternalDescription')
class Meta:
app_label = u'backend'
db_table = u'ORDER'
database_name = 'production'
To get the result by an query would be as follow:
SELECT
co.order_number, co.order_type, po.status
FROM
CurtainOrder co
INNER JOIN
[production].dbo.ProductionOrder po on po.order_number = co.order_number
But how can I get the same result in Django code?
I have tried to use SQL query in Django, https://docs.djangoproject.com/en/1.8/topics/db/sql/, like below:
from django.db import connections
cursor = connections['default'].cursor()
sql = """SELECT
co.order_number, co.order_type, po.status
FROM
CurtainOrder co
INNER JOIN
[production].dbo.ProductionOrder po on po.order_number = co.order_number """
cursor.execute(sql)
row = cursor.fetchone()
This is returning the error: return Database.Cursor.execute(self, query)
OperationalError: near ".": syntax error
It's going wrong when the 'production' db is joined, but the SQL query is executed good by doing it directly in the database management app.

Related

SQLalchemy to get data from multiple table in single object

I have 3 tables, users, projects and project_users is_admin table and I am trying to write ORM to get data from them.
My Models are here: https://pastebin.com/ZrmhKyNL
In simple SQL, we could join and select particular columns and get the desired output. But in ORM when I write query like this:
sql = """ select * from
projects p, users u, projects_users pu
where
p.name = '%s' and
p.id = pu.project_id and
pu.user_id = u.id and
p.is_active = true and
u.is_active = true
""" % project_name
and it works well and returns response in this format:
[
{
All columns of above 3 tables.
}
]
But when I try to convert this to sqlalchamey ORM, it doesn't work well:
return (
db.query(User)
.filter(Project.id == ProjectsUser.project_id)
.filter(ProjectsUser.user_id == User.id)
.filter(Project.is_active == True)
.filter(User.is_active == True)
.filter(Project.name == project_name)
.all()
)
I want is_admin value to be returned along with user object. This seems very common use case, but I couldn't find any solution related to SQLalchemy ORM.
If this is a one-to-one relationship, meaning that for every user you can have one and only one entry in the admin table, you could add a column to serve as back-reference:
class User(Base):
id = ...
name = ...
last_login = ...
admin = relationship("Admin", uselist=False, back_populates="user")
class Admin(Base):
id = ...
is_admin = ...
user_id = Column(Integer, ForeignKey('user.id'))
user = relationship("User", back_populates="admin")
Then you can query only the table user, and access the values from the relationship via user.admin.is_admin.
Read more:
One To One - SqlAlchemy docs
relationship.back_populates - SqlAlchemy docs

How to use temp table count values into into the where query in Django Raw Sql?

I need to use raw sql in my django project. I'm using count command and then I associated it with as command like "the_count" but i got an error. The error like this, the_count does not exist.
And my my code here,
# First Model
class AModel(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
name = models.CharField(max_lenth=100)
# Second Model
class BModel(models.Model):
a_model = models.ForeignKey(AModel, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
query = 'SELECT "app_AModel"."id",
(SELECT COUNT(*) FROM "app_BModel" INNER JOIN ON ("app_BModel"."user_id" = "app_AModel"."user_id") WHERE ("app_BModel"."a_model_id" = "app_AModel"."id")) AS "the_count"
FROM "app_AModel"
WHERE ("the_count" = 0)'
BModel.objects.raw(query)
Thank you for yours helps...
From postgreSQL documentation
An output column's name can be used to refer to the column's value in
ORDER BY and GROUP BY clauses, but not in the WHERE or HAVING clauses;
there you must write out the expression instead.
Also you probably want to use GROUP BY and HAVING on my_app table instead so something in a line of following:
SELECT a_model_id, COUNT(*) from app_BModel GROUP BY a_model_id HAVING count(*) > 0

Peewee query with join doesn't work as expected

I'm new to peewee and currently trying to migrate from normal Python SQlite3 library.
While my code generate a valid SQL query that return result as expected using a SQlite DB browser, trying to get the value of a field return AttributeError: x object has no attribute y.
Model:
class TableShows(BaseModel):
sonarr_series_id = IntegerField(column_name='sonarrSeriesId', unique=True)
title = TextField()
class Meta:
table_name = 'table_shows'
class TableHistory(BaseModel):
sonarr_series_id = ForeignKeyField(TableShows, field='sonarr_series_id', column_name='sonarrSeriesId')
class Meta:
table_name = 'table_history'
Peewee Query:
data = TableHistory.select(
TableShows.title,
TableHistory.sonarr_series_id
).join(
TableShows
).order_by(
TableShows.title.asc()
)
Resulting SQL query:
SELECT "t1"."title", "t2"."sonarrSeriesId"
FROM "table_history" AS "t2"
INNER JOIN "table_shows" AS "t1" ON ("t2"."sonarrSeriesId" = "t1"."sonarrSeriesId")
ORDER BY "t1"."title" ASC
Resulting dicts():
{'title': u'Test title', 'sonarr_series_id': 1}
Why does running this:
for item in data:
print item.title
Return this:
AttributeError: 'TableHistory' object has no attribute 'title'
http://docs.peewee-orm.com/en/latest/peewee/relationships.html#selecting-from-multiple-sources
You access the data via item.sonarr_series_id.title
You might consider naming your fields something a bit more pythonic.

Django ORM join subtable in query

I want use Django ORM. I build SQL query:
select itinerary.id, count(users.home_location_id) from itinerary_itinerary as itinerary left join (select to_applicationuser_id as id, users.home_location_id from custom_auth_applicationuser_friends as friends join custom_auth_applicationuser as users on friends.to_applicationuser_id = users.id where from_applicationuser_id = 28)
as users on itinerary.location_id = users.home_location_id
WHERE user_id = 28
GROUP BY itinerary.id, users.home_location_id
Could anybody tell me how make left join with table from subquery?
28 is current user_id.
I use something like:
Itinerary.object.filter(user_id=28).extra(
tables=['(select to_applicationuser_id as id, users.home_location_id from custom_auth_applicationuser_friends as friends join custom_auth_applicationuser as users on friends.to_applicationuser_id = users.id where from_applicationuser_id = 28) as users'],
where=['itinerary.location_id = users.home_location_id']
)
But I got error
ProgrammingError relation "(select to_applicationuser_id as id,
users.home_location_id fro" does not exist
UPD
Models (it is just simple scheme):
class ApplicationUser(models.Model):
name = models.CharField(max_length=255)
home_location = models.ForeignKey(Location)
friends = models.ManyToManyFieled('self')
class Location(models.Model):
loc_name = models.CharFiled(max_length=255)
class Itinerary(models.Model):
user = models.ForeignKey(ApplicationUser)
location = models.ForeignKey(Location)
When you add tables with extra, they get added to the from list, which does not accept an sql statement.
I don't think you need to use extra at all here, you can get a similar query with the ORM without the need to join on a select statement. The following code, using filtering and annotations, will give the same results as much as I was able to understand your query:
ApplicationUser.objects.filter(
Q(itinerary__location_id = F('friends__home_location_id')) |
Q(friends__home_location__isnull=True),
id=28,
).values_list(
'itinerary__id', 'friends__home_location_id'
).annotate(location_count = Count('friends__home_location_id')
).values_list('itinerary__id', 'location_count')

how to join two model of two separated database python peewee

I'm using peewee to use Mysql database.
import peewee
db_1 = peewee.MySQLDatabase('db_1', **{'user': 'root'})
db_2 = peewee.MySQLDatabase('db_2', **{'user': 'root'})
class User(peewee.Model):
id = peewee.PrimaryKeyField()
username = peewee.CharField()
class Meta:
database = db_1
class Tweet(peewee.Model):
id = peewee.PrimaryKeyField()
tweet = peewee.CharField()
user = peewee.IntegerField(db_column='user_id')
class Meta:
database = db_2
I want to execute this code:
m = Tweet().select(Tweet, User).join(
User, join_type=JOIN_INNER, on=User.id == Tweet.user
).where(
User.id == 13
)
but it raises this error:
peewee.ProgrammingError: (1146, "Table 'db_2.user' doesn't exist")
How I can fix it?
I thinkbest solution for problem use view on second database.
I create a views of users into db_2 and that code is work.

Categories