Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

flask - FLASK_SQLAlchemy: query_factory usage -> 'sqlalchemy.util._collections.result' is not mapped"

This is the error I get: "sqlalchemy.orm.exc.UnmappedInstanceError: Class 'sqlalchemy.util._collections.result' is not mapped"

Objective: On the "Ride" query_select_field I wanna show the destination concatenated with the car model and plate which are stored in Vehicle object. I need to submit and keep track of Ride.id. The working example below just show destination so if there is same destination served by two different vehicles I wouldn't be able to discrimminate.

enter image description here

The Form:

def list_rides():
    a = Ride.query.join(Vehicle).filter(Vehicle.operator_id==current_user.id).all()
    rides = (db.session.query(Ride, Vehicle)
        .join(Vehicle, Vehicle.id == Ride.vehicle_id)
        .filter(Vehicle.operator_id == current_user.id)
        .all()
    )
    print(rides)
    return a
    

class AddForm(FlaskForm):
    
    ride_id = QuerySelectField(u'Ride',      
                               validators=[DataRequired()],
                               query_factory=list_rides)
    dep_date = DateField('Departure date', default=datetime.today, validators=[DataRequired()])
    dep_time = TimeField('Departure Time:', default=datetime.now, validators=[DataRequired()])
    max_seats= IntegerField('Max Seats:', default=8, render_kw={'enabled':''}, validators=[DataRequired()])
    price = FloatField('Price:', default=9.0)
    notes = TextAreaField('Notes:')
    submit = SubmitField('Add schedule')

The code is working when I return "a" in the sense that Ride queryselectfield is populated with Ride repr . I cannot modify the repr object as I cannot call the Vehicle model which is part of a different Table/Model (Vehicle).

print(rides) output:

[(Monte Nudo, Ford Transit WCF556GP), (Monte Nono, Ford Transit WCF556GP), (Peak Snow, Ford F350 CA 90210)]

but when I return "rides" instead of "a" in list_rides() I get the error above mentioned.

models.py

    class Vehicle(db.Model):
    
    __tablename__ = 'vehicles'

    users = db.relationship(User)

    id = db.Column(db.Integer,primary_key = True)
    created_at = db.Column(db.DateTime)
    make = db.Column(db.Text)
    operator_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
    plate = db.Column(db.Text, unique=True)
    descr = db.Column(db.Text)
    is_active = db.Column(db.Boolean)

    def __init__(self, operator_id, make, plate, vehicle_description, is_active):
        self.operator_id = operator_id
        self.make = make
        self.plate = plate
        self.descr = vehicle_description
        self.created_at = datetime.datetime.now()
        self.is_active = is_active

    def __repr__(self):
        return f"{self.make} {self.plate}"

class Ride(db.Model):

    __tablename__ = 'rides'

    vehicles = db.relationship(Vehicle)

    id = db.Column(db.Integer,primary_key = True)
    created_at = db.Column(db.DateTime)
    name = db.Column(db.Text)
    vehicle_id = db.Column(db.Integer, db.ForeignKey('vehicles.id'), nullable=False)
    notes = db.Column(db.Text)


    def __init__(self, name, vehicle_id, notes):
        self.notes = notes
        self.vehicle_id = vehicle_id
        self.name = name
        self.created_at = datetime.datetime.now()

    def __repr__(self):
        return f"{self.name}"

The long story short is that I don't want to use repr of Ride to populate the queryselectfield but build my own.

Thanks.

question from:https://stackoverflow.com/questions/65651831/flask-sqlalchemy-query-factory-usage-sqlalchemy-util-collections-result-i

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Thanks to @snakecharmerb comment I tried to solve it by creating a one-to-many backref in the SQLALachemy model under Ride model.

vehicle = db.relationship('Vehicle', backref="ride", uselist=False)

and updating repr:

return f"{self.name} - {self.vehicle.make} - {self.vehicle.plate}"


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...