4

I have been given access to a database (MySQL, in case it matters) to access some data that I need, but I don't have direct access to the tables, the data is exposed through a SQL View.

I want to wrap this in a small API using flask. For the database connection I intend to use SQLAlchemy (just because it's the only databse wrapper that I know in python).

The thing is, I have read a lot of documentation, and dozens of stackoverflow posts and guides through the Internet, and I can't seem to find a way to query SQL Views from flask-SQLAlchemy.

In the documentation, they always use Models. I tried to define my View as a Model, but I get could not assemble any primary key columns for mapped table 'MySQLView'.

What I tried to do:

class MyView(db.Model):
    __tablename__ = "my_view_name_in_sql"
    db.Column("id", db.Integer, primary_key=True)
    db.Column("sample_id", db.String)
    {...etc}

Is there a way to do this, or maybe I should opt-out of using flask-SQLAlchemy and use something else instead?

3 Answers 3

2

There's a few answers here I think deal with your case, especially LeoRochael's answer who suggests using the https://pypi.org/project/sqlalchemy-views/ package. I suggest checking if you can - or cannot access the database's metdata, I think that could really help you avoid having to make models manually

db_engine = sqlalchemy_package.create_engine("mysql+...")
db_metadata = db.MetaData(bind=db_engine)

you can then either try making a Table directly, or use the metadata to make views like in the answer I linked.

your_table = db.Table("my_view_name_in_sql", db_metadata, autoload=True)
view_definition = your_table.select()
your_view = CreateView(your_table, view_definition, or_replace=True)
Sign up to request clarification or add additional context in comments.

Comments

2

I don't have experience with SQLAlchemy Flask but this is what worked for me in SQLAlchemy. I used the __mapper_args__ attribute to define the private key for a view in my database.

db_metadata = MetaData()
Base = automap_base(metadata=db_metadata)

class MyView(Base):
    __table__ = Table("View_Name", db_metadata, autoload_with=engine, schema="My_Schema")
    __mapper_args__ = {'primary_key': [__table__.c['Primary_Column_Name']]}

Base.prepare()

Comments

0

Managed to do this through the following code:

query = text('select * from "view_name"')
result = connection.execute(query)
inserted_rows = result.mappings().all()

3 pointers here to keep in mind:

  1. Wrap query statement with sqlalchemy's text method
  2. "view_name" should be wrapped by double quotes
  3. Result from query is of CursorResult type and contains a mappings method to retrieve data

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.