Django rest framework cast foreign mysql foreign table column - python-3.x

please help me to convert cast foreign table(customers) first name
class LoandetailListSearch(generics.ListAPIView):
serializer_class = LoandetailSerializer
def get_queryset(self):
"""
Optionally restricts the returned loan details to a search list,
by filtering against a `fields` in query parameter in the URL.
"""
queryset = Loandetails.objects.all().exclude(broker_name__isnull=True).\
extra(
{
'staff': "CONVERT(CAST(CONVERT(CONCAT(staff ) using latin1) as binary) using utf8)",
'customer__first_name': 'SELECT CONVERT(CAST(CONVERT(CONCAT(first_name ) using latin1) as binary) using utf8) as first_name FROM customers WHERE customers.id = loan_details.customer_id'
}).\
extra(select={'customer__first_name': 'SELECT CONVERT(CAST(CONVERT(CONCAT(first_name ) using latin1) as binary) using utf8) as first_name FROM customers WHERE customers.id = loan_details.customer_id' })
return queryset
I tried to convert and cast both methods first_name, But no luck. Thanks

Related

Django Subquery many values

class Category(models.Model):
name = models.CharField(max_length=100)
date = models.DateTimeField(auto_now=True)
class Hero(models.Model):
name = models.CharField(max_length=100)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
I want Categoty model name, data, id
In cookbook , I wrote the code as above.
hero_qs = Hero.objects.filter(
category=OuterRef("pk")
).order_by("-benevolence_factor")
Category.objects.all().annotate(
most_benevolent_hero=Subquery(
hero_qs.values('name')[:1]
)
)
It seems that only one value can be entered in hero_qs.values('name')
Is it possible to get name, data, id with one annotate?
You can try Concatenating the fields if you really want to use a single annotation
from django.db.models import Subquery, OuterRef, CharField, Value as V
from django.db.models.functions import Concat
hero_qs = Hero.objects.filter(
category=OuterRef("pk")
).order_by("-benevolence_factor").annotate(
details=Concat('name', V(','), 'id', output_field=CharField())
)
Category.objects.all().annotate(
most_benevolent_hero=Subquery(
hero_qs.values('details')[:1]
)
)
Then you can use string interpolation to separate that data out which is a relatively inexpensive operation
name, id = category.most_benevolent_hero.split(',')

fetching not with custom primary id in django

I have created a table in which the primary id have to customize id product_id like
class Product(models.Model):
product_id = models.BigIntegerField(auto_created = True,primary_key = True, unique=True)
name = models.CharField(max_length=200)
ref = models.CharField(max_length=100)
number= models.CharField(max_length=100)
class Meta:
db_table = "products"
def __str__(self):
return self.name
after creating the record I want to get the id of the latest record but when I retrieve the data with this id getting None
product = Product.objects.create(name=name, ref=ref, number=number)
print(product.product_id)
product.product_id id getting null
Pleae give me a solution to why this is happening.
Django will set the primary key of an AutoField or BigAutoField, given that the database supports returning the assigned primary key.
You thus should rewrite the model to:
class Product(models.Model):
product_id = models.BigAutoField(primary_key=True)
# …
The reason for this is that Django does not know what the primary key (pk) of the object is going to be before the object is saved in the database.
That is because Django does not determine the value of the pk for the incoming object, your database does. In order to get the pk, you first have to save the object then retrive its pk.

In MySQL 8, is there an index I can create to speed up LIKE searches?

I'm using Django 3, Python 3.8 and MySql 8. I have the following Django model in which I create a search based on a partial name ...
class Coop(models.Model):
objects = CoopManager()
name = models.CharField(max_length=250, null=False)
types = models.ManyToManyField(CoopType, blank=False)
addresses = models.ManyToManyField(Address)
enabled = models.BooleanField(default=True, null=False)
phone = models.ForeignKey(ContactMethod, on_delete=models.CASCADE, null=True, related_name='contact_phone')
email = models.ForeignKey(ContactMethod, on_delete=models.CASCADE, null=True, related_name='contact_email')
web_site = models.TextField()
...
# Look up coops by a partial name (case insensitive)
def find_by_name(self, partial_name):
queryset = Coop.objects.filter(name__icontains=partial_name, enabled=True)
print(queryset.query)
return queryset
The code above produces this query ...
SELECT `directory_coop`.`id`, `directory_coop`.`name`, `directory_coop`.`enabled`, `directory_coop`.`phone_id`, `directory_coop`.`email_id`, `directory_coop`.`web_site` FROM `directory_coop` WHERE (`directory_coop`.`enabled` = True AND `directory_coop`.`name` LIKE %Credit%)
Below is the table that Django migrations produced. Is there any kind of index or other adjustment I can make to speed up these queries -- specifically, the "name LIKE %Credit%" part?
CREATE TABLE `directory_coop` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(250) COLLATE utf8mb4_unicode_ci NOT NULL,
`enabled` tinyint(1) NOT NULL,
`phone_id` int DEFAULT NULL,
`email_id` int DEFAULT NULL,
`web_site` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
KEY `directory_coop_email_id_c20abcd2` (`email_id`),
KEY `directory_coop_phone_id_4c7e2178` (`phone_id`),
CONSTRAINT `directory_coop_email_id_c20abcd2_fk_directory_contactmethod_id` FOREIGN KEY (`email_id`) REFERENCES `directory_contactmethod` (`id`),
CONSTRAINT `directory_coop_phone_id_4c7e2178_fk_directory_contactmethod_id` FOREIGN KEY (`phone_id`) REFERENCES `directory_contactmethod` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=993 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
The SQL query will not speedup with regular indexing with like operator, but you can use MySQL's full-text search functions on a FULLTEXT indexed column
For that, you need to index the name column manually using SQL query since Django doesn't have that functionality yet.
After enabling FULLTEXT index on the name column, you can use either the search lookup or Django Func(...) expression to query the data.
References
Creating FULLTEXT Indexes for Full-Text Search
MySQL 8.0 Full-Text Search Functions
Django MySQL full text search
What is Full Text Search vs LIKE
How to speed up SELECT .. LIKE queries in MySQL on multiple columns?

Change SQLAlchemy __tablename__

I am using SQLAlchemy to handle requests from an API endpoint; my database tables (I have hundreds) are differentiated via a unique string (e.g. test_table_123)...
In the code below, __tablename__ is static. If possible, I would like that to change based on the specific table I would like to retrieve, as it would be tedious to write several hundred unique classes.
from config import db, ma # SQLAlchemy is init'd and tied to Flask in this config module
class specific_table(db.Model):
__tablename__ = 'test_table_123'
var1 = db.Column(db.Integer, primary_key=True)
var2 = db.Column(db.String, index=True)
var3 = db.Column(db.String)
class whole_table_schema(ma.ModelSchema):
class Meta:
model = specific_table
sqla_session = db.session
def single_table(table_name):
# collect the data from the unique table
my_data = specific_table().query.order_by(specific_table.level_0).all()
Thank you very much for your time in advance.
You can use reflect feature of SQLAlchemy.
engine = db.engine
metadata = MetaData()
metadata.reflect(bind=engine)
and finally
db.session.query(metadata.tables[table_name])
If you want smoother experience with querying, as previous solution cannot offer one, you might declare and map your tables: tables = {table_name: create_table(table_name) for table_name in table_names}, where create_table constructs models with different __tablename__. Instead of creating all tables at once, you can create them on demand.

Trying to join two tables in sqlalchemy orm query, getting an error

Trying to join the tables below using this command:
Subscription.query.filter( return Subscription.query.filter(Subscription.watch_id == id).join(User).filter_by(watch_id=id)
I get this error:
sqlalchemy.exc.InvalidRequestError: Could not find a FROM clause to join from. Tried joining to <class 'app.user.model.User'>, but got: Can't find any foreign key relationships between 'wm_subscription' and 'user'.
Essentially my end goal is to get a query that gets a List of Users that share a watch_id. Not sure if the models or the query is correct. Anybody know what's wrong?
Database = declarative_base(cls=DbBase)
class Subscription(Database):
__tablename__ = 'wm_subscription'
subscription_id = UniqueIdPk()
watch_id = UniqueIdRefNotNull(index=True)
user_id = UniqueIdRefNotNull(ForeignKey('User.user_id'), index=True)
subscription_watch = relationship('Watch',
primaryjoin='Subscription.watch_id == Watch.watch_id',
foreign_keys='Watch.watch_id',
uselist=True)
subscription_user = relationship('User',
primaryjoin='Subscription.watch_id == User.user_id',
foreign_keys='User.user_id',
uselist=True,
backref='user')
class User(Database, UserMixin):
__tablename__ = 'user'
user_id = UniqueIdPk()
# Google sub ID - unique to user https://developers.google.com/identity/protocols/OpenIDConnect
google_id = Column(String(length=50))
# override email mixin for unique index
email = Email(unique=True)
first_name = Name()
last_name = Name()
def get_id(self):
return self.user_id
This is the correct query:
Subscription.query.filter(Subscription.watch_id == id).join(User)

Resources