I have two models Employee and AccessDr.
Employee Model=>
class Employee(models.Model):
empid = models.CharField(max_length=20, unique=True)
empname = models.CharField(max_length=50)
phone = models.CharField(max_length=20, blank=True)
token = models.ForeignKey(
Company, to_field='token', on_delete=models.CASCADE)
def __str__(self):
return "%s" % (self.empid)
class Meta:
managed = True
db_table = 'employee'
AccessDr Model=>
class AccessDr(models.Model):
empid = models.ForeignKey(
Employee, to_field='empid', on_delete=models.CASCADE)
_date = models.DateField()
_time = models.IntegerField()
device = models.CharField(max_length=5)
takey = models.CharField(max_length=3, default='00')
token = models.ForeignKey(
Company, to_field='token', on_delete=models.CASCADE)
def __str__(self):
return "%s %s" % (self.empid, self._date)
class Meta:
ordering = ['_date']
managed = True
db_table = 'tstrdoor'
I would like to return object when the request to AccessDr like SQL left join, Example json=>
{
empid:'',
empname:'', <=this one from employee model
phone:'', <=this one from employee model
_date:'',
_time:'',
.
.
}
How can I achieve that one?
have a look at this LEFT JOIN Django ORM
read this as well https://docs.djangoproject.com/en/2.2/topics/db/queries/#spanning-multi-valued-relationships
you can print query to look at how it translates to SQL by
Employes=AccessDr.objects.values('employee__empname','employee__phone')
print(Employes.query)
Are you using serializers in the views? in this case, you could create a serializer field
which will put agreement data as an array like this
class CustomerSerializer(serializers.ModelSerializer):
agreements = AgreementSerializer(many=True, read_only=True)
class Meta:
model = Customer
fields = [
'id',
'username',
'mail',
'fName',
'lName',
'fNameEng',
'lNameEng',
'personalId',
'phone',
'crmId', # "ID": "20995",
'agreements',
]
depth = 1
Are you using serializers in the views? in this case, you could create serializer field
which will put agreement data as an array like this
{
"id": 985,
"username": null,
"mail": "undefined",
"fName": "Merab",
"lName": "Dasv",
"fNameEng": "Merab",
"lNameEng": "Dasv",
"personalId": "01022342346003629",
"phone": "5912324234282331",
"crmId": 1439,
"agreements": [
{
"id": 884,
"signDate": "2015-04-16",
"accountDate": "2015-05-01",
"amount": 0,
"comBalance": -1445.0,
"status": 1,
"details": [
{
"square": 32.38,
"amount": 35.0,
"object": {
"id": 578,
"object": 2,
"block": 1,
"floor": 19,
"flat": "7",
"cadastre": "05.24.04.055.01.563",
"square": 32.38,
"pCounter": 25915123146,
"wCounter": 104412312435,
"accountDate": "2015-04-01T00:00:00",
"comBalance": -1445.0,
"comDeptAmount": 1895.0,
"rentDate": null,
"active": 1,
"finaAmount": 0,
"crmId": 0
}
},
]
},
]
}
Related
I am new to FastAPI and SQL-Alchemy, I am having trouble creating a schema and relationship of the many-to-many table (association table).
Here is an example, a student can enroll in multiple courses and a single course can have multiple students thus making many-to-many relationship.
Database Models
class Student(Base):
__tablename__ = "student"
id = Column(Integer, primary_key=True, index=True)
name = Column(String, nullable=False)
class Course(Base):
__tablename__ = "course"
id = Column(Integer, primary_key=True, index=True)
name = Column(String, nullable=False)
class StudentCourse(Base):
__tablename__ = "student_course"
id = Column(Integer, primary_key=True, index=True)
student_id = Column(Integer, ForeignKey("student.id"), nullable=False)
course_id = Column(Integer, ForeignKey("course.id"), nullable=False)
What relation do I need to define and how to design a schema from which I can get the following responses:
Response 1
[
{
"id": 1,
"name": "Student A",
"courses": [
{
"id": 1,
"name": "Course A"
},
{
"id": 2,
"name": "Course B"
}
]
},
{
"id": 2,
"name": "Student B",
"courses": [
{
"id": 1,
"name": "Course A"
},
{
"id": 3,
"name": "Course C"
}
]
},
{...}
]
Response 2
[
{
"id": 1,
"name": "Course A",
"students": [
{
"id": 1,
"name": "Student A"
},
{
"id": 2,
"name": "Student B"
}
]
},
{
"id": 2,
"name": "Course B",
"students": [
{
"id": 1,
"name": "Student A"
},
]
},
{
"id": 3,
"name": "Course C",
"students": [
{
"id": 2,
"name": "Student B"
},
]
},
{...}
]
In my opinion, it is simpler and preferable to use an association table instead of an association object for this many-to-many relationship, since you don't need extra fields.
So, according to the documentation, your database models should be:
student_course = Table("student_course", Base.metadata,
Column("student_id", ForeignKey("student.id"), primary_key=True),
Column("course_id", ForeignKey("course.id"), primary_key=True))
class Student(Base):
__tablename__ = "student"
id = Column(Integer, primary_key=True)
name = Column(String, nullable=False)
courses = relationship("Course",
secondary=student_course,
back_populates="students")
class Course(Base):
__tablename__ = "course"
id = Column(Integer, primary_key=True)
name = Column(String, nullable=False)
students = relationship("Student",
secondary=student_course,
back_populates="courses")
and your pydantic models (schemas):
class Student(BaseModel):
id: int
name: str
class Config:
orm_mode = True
class Course(BaseModel):
id: int
name: str
class Config:
orm_mode = True
class StudentOut(Student):
courses: List[Course]
class CourseOut(Course):
students: List[Student]
where StudentOut and CourseOut are your response models
models.py
class Employees(models.Model):
emp_no = models.IntegerField(primary_key=True)
birth_date = models.DateField()
first_name = models.CharField(max_length=14)
last_name = models.CharField(max_length=16)
gender = models.CharField(max_length=1)
hire_date = models.DateField()
class Meta:
managed = False
db_table = 'employees'
class Salaries(models.Model):
emp_no = models.ForeignKey(Employees, models.DO_NOTHING, db_column='emp_no',related_name='salaries', primary_key=True)
salary = models.IntegerField()
from_date = models.DateField()
to_date = models.DateField()
class Meta:
managed = False
db_table = 'salaries'
unique_together = (('emp_no', 'from_date'),)
Mysql raw query:
SELECT `employees`.`emp_no`, `employees`.`birth_date`, `employees`.`first_name`, `employees`.`last_name`, `employees`.`gender`, `employees`.`hire_date`,
(
SELECT JSON_ARRAYAGG(
JSON_OBJECT(
'salary', `salaries`.`salary`,
'from_date', `salaries`.`from_date`,
'to_date', `salaries`.`to_date`
)
) FROM `salaries` WHERE (`employees`.`emp_no` = `salaries`.`emp_no`)
) as salaries
FROM `employees`
INNER JOIN `salaries` root_salaries ON `root_salaries`.`salary` > 60000
WHERE `employees`.`emp_no` = `root_salaries`.`emp_no` LIMIT 100 OFFSET 100
Output for raw query:
[
{
"emp_no": 10017,
"birth_date": "1958-07-06",
"first_name": "Cristinel",
"last_name": "Bouloucos",
"gender": "F",
"hire_date": "1993-08-03",
"salaries": [
{
"salary": 71380,
"to_date": "1994-08-03",
"from_date": "1993-08-03"
},
{
"salary": 75538,
"to_date": "1995-08-03",
"from_date": "1994-08-03"
}
]
},
{
"emp_no": 10018,
"birth_date": "1954-06-19",
"first_name": "Kazuhide",
"last_name": "Peha",
"gender": "F",
"hire_date": "1987-04-03",
"salaries": [
{
"salary": 55881,
"to_date": "1988-04-02",
"from_date": "1987-04-03"
},
{
"salary": 59206,
"to_date": "1989-04-02",
"from_date": "1988-04-02"
},
{
"salary": 61361,
"to_date": "1990-04-02",
"from_date": "1989-04-02"
}
]
}
]
My question is how to generate the above raw query using Django ORM.
Thanks.
Views.py
query_set = Employees.objects.filter(salaries__salary__gt=60000).annotate(
salaries_1=Subquery(
Salaries.objects.filter(emp_no=OuterRef('emp_no'), salary__gt=60000).values(
salaries=JSONArrayAgg(JSONObject(
salary=F('salary'),
from_date=F('from_date'),
to_date=F('to_date')
))))
).distinct()[100:200]
employee_ser = EmployeesWithSalaryGroupSerializer(query_set, many=True)
data = employee_ser.data
Serializers.py
class EmployeesWithSalaryGroupSerializer(serializers.Serializer):
emp_no = serializers.IntegerField()
birth_date = serializers.DateField()
first_name = serializers.CharField()
last_name = serializers.CharField()
gender = serializers.CharField()
hire_date = serializers.DateField()
salaries_1 = serializers.JSONField()
def to_representation(self, instance):
ret = super(EmployeesWithSalaryGroupSerializer, self).to_representation(instance=instance)
ret['salaries'] = json.loads(instance.salaries_1)
ret.pop('salaries_1')
return ret
i am really new to DRM and i have to following problem
I have three related models. Now i want to for each sensor values to the related patient. My models look like:
class Sensor(models.Model):
sensor_name = models.CharField(max_length=200, primary_key=True)
sensor_refreshRate = models.FloatField()
sensor_prio = models.IntegerField(choices=[
(1, 1), (2, 2), (3, 3), (4, 4), ], default='1')
sensor_typ = models.CharField(
max_length=200,
choices=[
('bar', 'bar'), ('pie', 'pie'),
('line', 'line'), ('text', 'text'),
],
default='bar'
)
class Patient(models.Model):
firstName = models.CharField(max_length=200)
lastName = models.CharField(max_length=200)
age = models.IntegerField()
doctor = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
sensor = models.ManyToManyField(Sensor)
class Value(models.Model):
value_date = models.DateTimeField(auto_now_add=True)
value = models.FloatField()
sensor = models.ForeignKey(Sensor, on_delete=models.CASCADE)
Now i would like to send a JSON file which looks like:
[
{
"value": 445.0,
"sensor": "Pressure",
"patient": 3
},
{
"value": 478.0,
"sensor": "Temperature",
"patient": 3
}
]
Now i am not sure how to serialize my JSON.
Thanks in advance
your data models seems incomplete.
There's no link between the Value model and the Patient one.
So first I'd suggest to modify the Value model
class Value(models.Model):
value_date = models.DateTimeField(auto_now_add=True)
value = models.FloatField()
sensor = models.ForeignKey(Sensor, on_delete=models.CASCADE)
patient = models.ForeignKey(Patient, on_delete=models.CASCADE)
then you could create a queryset
qs = Value.objects.filter(.....).values(
'patient_id', 'sensor__sensor_name', 'value'
)
and the write your serializer
I am new in Django rest API. I create an API for my project where user can get data from the system via API. I serialize data and pass also but I also want to count the result and pass that value too.
my view.py is here
def categorySearch(request, slug):
itemViewCategory = Item.objects.raw('''select *, company.slug as companySlug, company.name as companyName,
field.id as fieldId, field.name as fieldName, category.name as categoryName from company
inner join category on company.business_type = category.id inner join category_field on
category_field.category_id = category.id inner join custom_field as field on category_field.field_id = field.id
where category.id = (select id from category where slug= %s) and field.name LIKE %s order by company.name ''', [slug, product])
itemViewCategoryCount = Item.objects.raw(
'''select *, COUNT(company.name) as companyCount from company inner join category on
company.business_type = category.id where category.id = (select id from category where slug= %s)
order by company.name ''', [slug])
results = []
for val in itemViewCategory:
place_json = {}
place_json['name'] = val.name
place_json['email'] = val.email
place_json['address'] = val.address
results.append(place_json)
return JsonResponse(results, safe=False)
where its return data like this
[
{
"name": "Washing Plants",
"email": "ababil.washing#yahoo.com",
"address": "ababil.washing#yahoo.com"
},
{
"name": "Washing Plants",
"email": "info#dekkoisho.com",
"address": "Holding # 79/1, Chandra, Kaliakoir"
},
{
"name": "Washing Plants",
"email": "aznmery90#yahoo.com",
"address": "79/8/2 Bibir Bagicha ( 4 No. Gate )\r\nNorth Jatrabari, Dhaka-1205."
},
]
But I want this type of data formate
{
"statuscode": "0",
"message": "Success",
"data": [
{
"companyName": "Adorn Knitwear Ltd.",
"phone": "01713047421",
"city": "Dhaka"
},
{
"companyName": "Adury Apparels Ltd.",
"phone": "029333274",
"city": "Dhaka"
},
{
"companyName": "Advance World Ltd.",
"phone": "01711537851",
"city": "Dhaka"
},
{
"companyName": "Afaku Apparels Ltd.",
"phone": "01711869977",
"city": "Dhaka"
}
],
"common": {
"totalCompany": "104",
}
}
Now how can I format my data like this?
for val in itemViewCategory:
place_json = {}
place_json['name'] = val.name
place_json['email'] = val.email
place_json['address'] = val.address
results.append(place_json)
final_result = {}
final_result['data'] = results
final_result["statuscode"] = 0
final_result["message"] = "success"
return JsonResponse(final_result,safe=False)
How can i select a name column from another table instead of id ,
example :
class Attendance(db.Model):
__tablename__ = 'zk_attendance'
id = db.Column(db.Integer,primary_key=True)
uid = db.Column(db.Integer,db.ForeignKey('zk_users.uid'))
date = db.Column(db.Date)
time = db.Column(db.Time)
device = db.Column(db.Integer,db.ForeignKey('devices.id'))
user = db.relationship('Users',backref=db.backref('user', lazy='dynamic'))
class Users(db.Model):
__tablename__ = 'zk_users'
uid = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String)
And if i want to select all attendance :
#app.route('/api/attendance/<string:date_from>/<string:date_to>',methods=['GET'])
def get_attend_date_date(date_from,date_to):
data = db.session.query(Attendance).filter(Attendance.date.between(date_from,date_to)).order_by(Attendance.date,Attendance.time)
attendance_schema = AttendanceSchema(many=True)
data = attendance_schema.dump(data).data
return jsonify({'attendance':data})
OUTPUT
{
"attendance": [
{
"Device": 4,
"date": "2016-01-18",
"id": 18805,
"time": "00:49:00",
"user": 30025
},
{
"Device": 4,
"date": "2016-01-18",
"id": 18902,
"time": "00:49:00",
"user": 30045
},
BUT
am getting the user uid , i want to return the user.name
Am using flask_marshmallow to serialize the data before send it as josn , to be able send the user name , i have to nest the name from the users schema as the following :
class UsersSchema(ma.Schema):
name = fields.String(dump_only=True)
class AttendanceSchema(ma.Schema):
date = fields.Date(dump_only=True)
user = fields.Nested(UsersSchema)