Long loading data in flask-admin relationship dropdown input - flask

How to reduce the amount of data in the related table when editing and inserting item form in Flask-admin.
In my related tables more than 500,000 records ...
And the flask-admin uploads all the data in the associated drop-down input (example film).... and can not do it.
I created my model mysql innodb through SQLAlchemy.
I can load the data in the parts table? or disable the loading of related data
class LfMailerQueue(db.Model):
__tablename__ = 'lf_mailer_queue'
mail_id = db.Column(db.Integer, primary_key=True)
template_id = db.Column(db.ForeignKey(u'lf_mailer.id'))
user_id = db.Column(db.ForeignKey(u'modx_user_attributes.internalKey'), index=True)
film_id = db.Column(db.ForeignKey(u'modx_lfvideo_items.id'), index=True)
email = db.Column(db.String(255))
fullname = db.Column(db.String(255))
status = db.Column(db.Integer, nullable=False, server_default=db.FetchedValue())
film = db.relationship(u'ModxLfvideoItem', primaryjoin='LfMailerQueue.film_id == ModxLfvideoItem.id', backref=u'lf_mailer_queues')
template = db.relationship(u'LfMailer', primaryjoin='LfMailerQueue.template_id == LfMailer.id', backref=u'lf_mailer_queues')
user = db.relationship(u'ModxUserAttribute', primaryjoin='LfMailerQueue.user_id == ModxUserAttribute.internalKey', backref=u'lf_mailer_queues')
class ModxLfvideoItem(db.Model):
__tablename__ = 'modx_lfvideo_items'
id = db.Column(db.Integer, primary_key=True)
group = db.Column(db.String(255), nullable=False, unique=True)
def __str__(self):
return self.group
....
class ModxUserAttribute(db.Model):
....

Related

Not able to get joins in flask Marshmellow and sql alchemy

I want to get the producttype with admin info who added the producttype I am using sqlalchemy with postgresql and marshmallow
This is my Model related info related to Admin
class Admin(db.Model):
id = db.Column(db.Integer, primary_key=True)
full_name = db.Column(db.String())
email = db.Column(db.String(), unique=True)
mobile = db.Column(db.String(), unique=True)
password = db.Column(db.String())
product_types: db.relationship("ProductType", backref="admin", lazy=True)
created_at = db.Column(DateTime(timezone=True), server_default=func.now())
updated_at = db.Column(DateTime(timezone=True), onupdate=func.now())
def __repr__(self):
return "<Admin %r>" % self.full_name
class AdminSchema(ma.SQLAlchemyAutoSchema):
class Meta:
model = Admin
admin_schema = AdminSchema()
admins_schema = AdminSchema(many=True)
This is my Model related info related to Product_Type
class ProductType(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String())
descripton = db.Column(db.String())
added_by_id = db.Column(db.Integer, db.ForeignKey("added_by.id"))
added_by: db.relationship("Admin", backref=db.backref("admin", lazy="dynamic"))
created_at = db.Column(DateTime(timezone=True), server_default=func.now())
updated_at = db.Column(DateTime(timezone=True), onupdate=func.now())
def __repr__(self):
return "<ProductType %r>" % self.name
class ProductTypeSchema(ma.SQLAlchemyAutoSchema):
class Meta:
model = ProductType
added_by = ma.Nested(AdminSchema)
product_type_schema = ProductTypeSchema()
product_types_schema = ProductTypeSchema(many=True)
If anyone can suggest something please do
I want to get the producttype with admin info who added the producttype I am using sqlalchemy with postgresql and marshmallow.
The output I am expecting
product_type:{
"created_at": "2023-01-21T07:55:14.773346+05:30",
"descripton": "Product Type",
"id": 6,
"name": "dgd",
"updated_at": null,
"admin":{
"full_name":""
"email":""
"mobile":""
}
}
Unfortunately, your code contains syntax errors as well as an inaccurate definition of the database relationships. For this reason it is difficult to interpret exactly what your database looks like or which renaming the schemas must contain.
As a note on defining relationships:
The referencing via ForeignKey expects the names of the table and the primary key column separated by a period.
The backref parameter defines the name of the attribute under which the back reference is accessible.
The following example shows a possible implementation to achieve the output you are aiming for.
class Admin(db.Model):
id = db.Column(db.Integer, primary_key=True)
full_name = db.Column(db.String())
email = db.Column(db.String(), unique=True)
mobile = db.Column(db.String(), unique=True)
password = db.Column(db.String())
created_at = db.Column(db.DateTime(timezone=True), server_default=func.now())
updated_at = db.Column(db.DateTime(timezone=True), onupdate=func.now())
class AdminSchema(ma.SQLAlchemyAutoSchema):
class Meta:
model = Admin
exclude = ('password',)
class ProductType(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String())
description = db.Column(db.String())
admin_id = db.Column(db.Integer, db.ForeignKey("admin.id"))
admin = db.relationship("Admin", backref=db.backref("product_types", lazy="dynamic"))
created_at = db.Column(db.DateTime(timezone=True), server_default=func.now())
updated_at = db.Column(db.DateTime(timezone=True), onupdate=func.now())
class ProductTypeSchema(ma.SQLAlchemyAutoSchema):
class Meta:
model = ProductType
admin = ma.Nested(AdminSchema(only=('full_name','mobile', 'email')))

Flask_sqlalchemy many to many query

I have created the following models:
tag_post = db.Table('tag_post',
db.Column('tag_id', db.Integer, db.ForeignKey('tag.id'), primary_key=True),
db.Column('post_id', db.Integer, db.ForeignKey('post.id'), primary_key=True))
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(180))
body = db.Column(db.Text, nullable=False)
tags = db.relationship('Tag', secondary=tag_post, backref=db.backref('posts_associated', lazy="dynamic"))
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
class Tag(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(20))
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64))
username = db.Column(db.String(64), index=True, unique=True)
email = db.Column(db.String(120), index=True, unique=True)
password_hash = db.Column(db.String(128))
posts = db.relationship('Post', backref='author', lazy='dynamic')
How can I query all the posts tagged with a tag, by using the tag.id?
Thanks in advance
The solution is to use a join.
You want all posts that meet a condition. The query should therefore start with the table Post.
Post.query
Then you bind the table posts with your join table using the two columns that should fit. In this case the column post_id in the tag_post table and id in the Post table. Since you use your association table directly, the columns used are referenced using the name via the attribute c.
Post.query\
.join(tag_post, tag_post.c.post_id == Post.id)
Then you filter the second column of your join table based on your condition.
tag_id = 1
Post.query\
.join(tag_post, tag_post.c.post_id == Post.id)\
.filter(tag_post.c.tag_id == tag_id)
Since you want all posts and not just one, close the request with all().
tag_id = 1
tagged_posts = Post.query\
.join(tag_post, tag_post.c.post_id == Post.id)\
.filter(tag_post.c.tag_id == tag_id)\
.all()
The following is a detailed query with the same result, which also includes the third table.
tag_id = 1
tagged_posts = Post.query\
.join(tag_post, tag_post.c.post_id == Post.id)\
.join(Tag, tag_post.c.tag_id == Tag.id)\
.filter(Tag.id == tag_id)\
.all()

How to combine and match 2 tables in Flask

The id is associated with the postID. How can I get the contact information and comment information of that id when I enter the id(/postComments/id)?
I'm getting an internal error...
class posts(db.Model):
__tablename__ = "posts"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100))
postName = db.Column(db.String(100))
postDescription = db.Column(db.String(500))
postLike = db.Column(db.Integer)
class postComment(db.Model):
__tablename__ = "postComment"
id = db.Column(db.Integer, primary_key=True)
postID = db.Column(db.Integer)
senderName = db.Column(db.String(20))
commentPost = db.Column(db.String(300))
#app.route('/postComments/<id>',methods=['GET'])
def get_comment_post(id):
userList = posts.query\
.join(postComment, posts.id == postComment.postID)\
.add_columns(posts.id, posts.name, posts.postDescription, postComment.commentPost, postComment.senderName)\
.filter(posts.id == id)
Modify your models (and perform migrations) to allow reference for foreign keys:
class postComment(db.Model):
__tablename__ = "postComment"
id = db.Column(db.Integer, primary_key=True)
postID = db.Column(db.Integer, db.ForeignKey("posts.id")) # <--- Set to Foreign Key
senderName = db.Column(db.String(20))
commentPost = db.Column(db.String(300))
# Establish relationship
post = db.Relationship("posts", backref="postComment") # <--- backref makes this relationship available in the other class
# This should get simpler...
#app.route('/postComments/<id>',methods=['GET'])
def get_comment_post(id):
# Get the comment based on id
my_comment = postComment.query.get(id)
# Get the post associated with that comment
my_post = my_comment.post
# It looks like you're doing an intricate data transformation.
# Do that here...
# Also, for debugging, consider using the following print statements
print(my_comment.__dict__)
print(my_post.__dict__)
Consider reading this slightly more detailed explanation for establishing relationships.

Can't get Association table to eager load with Movie for particlular User, to show if the User who added the movie is being followed or not Flask

class Movie(db.Model):
__searchable__ = ['genre']
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(200))
timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
username = db.Column(db.String(255))
description = db.Column(db.String(100))
class User(db.Model,UserMixin):
__tablename__ = 'user'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), index=True, unique=True)
email = db.Column(db.String, nullable=False)
password = db.Column(db.String, nullable=False)
movies = db.relationship('Movie', backref='author', lazy='joined')
followed = db.relationship('User', secondary=followers,
primaryjoin=(followers.c.follower_id==id),
secondaryjoin=(followers.c.followed_id==id),
backref=db.backref('followers', lazy='joined'), lazy='joined')
followers = db.Table('followers',
db.Column('follower_id', db.Integer, db.ForeignKey('user.id'), primary_key = True),
db.Column('followed_id', db.Integer, db.ForeignKey('user.id'), primary_key = True) )
def get_all_movies_follow():
qry = Movie.query.order_by(Movie.id.desc()).all()
movies_schema = MovieSchema(many=True)
return movies_schema.dump(qry)
How to get back an collection (array) where I have a property that shows whether
When I eager_load followers table it's still won't show up in the query.
``` #movi = Movie.query.outerjoin(followers, followers.c.followed_id == Movie.user_id).options(contains_eager( Movie.us).contains_eager( 'followers')).order_by(Movie.id.desc()).all()
Also when I try to use follow unfollow function I get Select statement 'SELECT *
FROM followers, movie AS movie_1
WHERE followers.followed_id = movie_1.user_id' returned no FROM clauses due to auto-correlation; specify correlate(<tables>) to control correlation manually.
which in short is def unfollow(id):
...
current_user.unfollow(user)
db.session.commit()
def follow(self, user):
if not self.is_following(user):
self.followed.append(user)
def unfollow(self, user):
if self.is_following(user):
self.followed.remove(user)
def is_following(self, user):
return self.query.filter(followers.c.followed_id==user.id).count()>0
So I tried adding this to Movie class: ```following = column_property( exists().where(followers.c.followed_id==user_id)) but it has to be also restricted on current_user.id=followers.c.follower_id
I am thinking maybe statement that will be included when I query for the Movie
ok, so this works, granted that I included following in the schema to dump on MovieSchema.
But it has a problem. If there are no matches to (followers.c.follower_id) so user is not following anyone. then I get an empty result and no movie gets loaded at all.
class Movie(db.Model)
...
following = column_property( exists().where(followers.c.followed_id==user_id).correlate_except(followers))
and in query
qry = db.session.query(Movie).filter(followers.c.follower_id == current_user.id).all()

Flask: how to add related One-to-Many models from forms

I have two models with One-to-Many relations
first_model
class Datacenter(db.Model):
id = db.Column(db.Integer, primary_key=True)
number = db.Column(db.Integer)
name = db.Column(db.String(64), index=True, unique=True)
place = db.Column(db.String(64))
capacity = db.Column(db.Integer, index=True)
server = db.relationship('Server', backref='datacenter', lazy=True)
tier = db.Column(db.Integer)
def __repr__(self):
return '<Datacenter {}>'.format(self.name)
second_models
class Server(db.Model):
id = db.Column(db.Integer, primary_key=True)
number = db.Column(db.Integer)
name = db.Column(db.String(64), index=True, unique=True)
factory = db.Column(db.String(64), index=True)
model = db.Column(db.String(64))
serial = db.Column(db.Integer)
os = db.Column(db.String(64))
datacener_id=db.Column(db.Integer, db.ForeignKey('datacenter.id'), nullable=False)
def __repr__(self):
return '<Server {}>'.format(self.name)
However, I'm not sure that I correctly described the relationship between them in the fields of the model.
All I need is to create a new Server model with a connection to the Datacenter model.
I think that this can be done using the select field in the form. so I created a form
class ServerForm(FlaskForm):
number = IntegerField('Number')
name = StringField('Name')
factory = StringField('Factory')
model = StringField('Model')
serial = IntegerField('Model')
os = StringField('OS')
datacener_id = SelectField('Datacener', choices=[ ???? ])
and router
#app.route('/add_server', methods = ['POST', 'GET'])
def add_server():
form = ServerForm(request.form)
if request.method=='POST' and form.validate():
data = Server(
number=form.number.data,
name=form.name.data,
factory=form.factory.data,
model=form.model.data,
serial=form.serial.data,
os=form.os.data,
datacener_id=form.datacener_id.data
)
db.session.add(data)
db.session.commit()
flash('Server created successfully!')
return redirect('/')
return render_template('new_server.html', form=form)
But when I go to the page for adding a new model, the drop-down list is empty. Tell me what I need to change in my code