4

I am trying to store images in my sqlite database as BLOB data-type and then display the images on my webpage but i keep getting a sqlalchemy error (Am using sqlalchemy as my ORM), error:

sqlalchemy.exc.StatementError
StatementError: buffer object expected (original cause: TypeError: buffer object expected) u'INSERT INTO room (owner_name, size, description, price, address, owner_number, room_image, university_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?)' [{'owner_name': u'Thomas Jefferson', 'description': u'Master Bedroom, Non-furnished, toilet attached', 'price': u'RM650/Month', 'room_image': <FileStorage: u'udacity.png' ('image/png')>, 'university_id': 1, 'address': u'Cyber Heights Villa', 'size': u'325sqft', 'owner_number': u'+60111223456'}]

Here are my codes: 1.) my database setup file (i have the BLOB Column in the room table) :

import sys
from sqlalchemy.dialects.sqlite import BLOB
from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from sqlalchemy import create_engine
Base = declarative_base()


class University(Base):

    __tablename__ = "university"

    #column definitions for the university table
    id = Column(Integer, primary_key=True)
    name = Column(String(250), nullable=False)
    city = Column(String(80), nullable=False)

    @property
    def serialize(self):
        #Returns object data in easilty serializable format
        return{
            "name": self.name,
            "city": self.city,
            "id": self.id,
        }


class Room(Base):

    __tablename__ = "room"

    #column definitions for the room table
    owner_name = Column(String(90), nullable=False)
    id = Column(Integer, primary_key=True)
    size = Column(String(60))
    description = Column(String(250))
    price = Column(String(10))
    address = Column(String(250))
    owner_number = Column(String(15))
    room_image = Column(BLOB)
    university_id = Column(Integer, ForeignKey("university.id"))
    university = relationship(University)

engine = create_engine("sqlite:///gotroom.db")
Base.metadata.create_all(engine)

2.) this is my python file code where i intend to allow uploading of images as BLOB into room_image (within newRoom function is where the upload for a photo image is to take place and stored in room_image Column in my room table):

#show rooms for a university
@app.route("/university/<int:university_id>/")
@app.route("/university/<int:university_id>/rooms/")
def showRooms(university_id):
    university = session.query(University).filter_by(id=university_id).one()
    rooms = session.query(Room).filter_by(university_id=university_id).all()
    return render_template("rooms.html", rooms=rooms, university=university)


#create a new room for a particular university
@app.route("/university/<int:university_id>/rooms/new/", methods=["GET", "POST"])
def newRoom(university_id):
    if request.method == "POST":
        aNewRoom = Room(owner_name=request.form["ownerName"], size=request.form["roomSize"]\
                       , description=request.form["roomDescription"], price=request.form["roomPrice"]\
                        , address=request.form["adress"], owner_number=request.form["phoneNum"], \
                        room_image=request.files["roomImage"], university_id=university_id)

        session.add(aNewRoom)
        session.commit()

        #feedback to user
        flash("New Room Created")       

        return redirect(url_for("showRooms", university_id=university_id))
    else:
        return render_template("newroom.html", university_id=university_id)

3.) here is the form template code for creating a new room "newroom.html" (i have to allow the upload for the image):

<form action="{{url_for('newRoom', university_id=university_id)}}" method="POST" enctype='multipart/form-data'>
    <div class="row">
        <div class="col-md-4">
            <input type="text" class="form-control" name="ownerName" placeholder="Name">
        </div>

        <div class="col-md-3">
            <input type="text" class="form-control" name="phoneNum" placeholder="Contact Number">
        </div>

        <div class="col-md-5">
            <input type="text" class="form-control" name="adress" placeholder="Address">
        </div>
    </div><!--first row-->
    </br>
    <div class="row">
        <div class="col-md-2">
            <input type="text" class="form-control" name="roomSize" placeholder="Room Size">
        </div>

        <div class="col-md-2">
            <input type="text" class="form-control" name="roomPrice" placeholder="Room Price/Month">
        </div>
    </div><!--second row-->
    </br>
    <div class="row">
        <div class="col-md-4" style="height: 100px">
            <input type="text" class="form-control" name="roomDescription" placeholder="Room Details" style="height: 100%">
        </div>
        <input type='file' name='roomImage'>
    </div>
    </br>

    <input type="submit" value="Post Room" class="btn btn-success btn-lg" role="button">

</form> 

4.) and here is the template code where i want to display all the information including the image:

        </br>

        <img src="{{room.room_image}}">
        <strong>Owner Name</strong>: {{room.owner_name}}

        </br>
        <strong>Contact Number</strong>: {{room.owner_number}}
        </br>
        <strong>Home Address</strong> : {{room.address}}
        </br>
        <strong>Room Price</strong> : {{room.price}}
        </br>
        <strong>Room Size</strong>  : {{room.size}}
        </br>
        <strong>Room Description</strong>: {{room.description}}
        <div>

Anytime i remove the image, i do not get the error, but as soon as i try to display the image, the error comes back, could any please help me out with this? i can provide more details or code if needed

1 Answer 1

2

From the error it seems that you are trying to pass the wrong type. I believe BLOB expects a binary whereas you are passing a png. There is a make_blob() method that you can use to convert the image to a binary. Check this page, it should be helpful.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.