Replies: 15 comments
-
|
I would certainly not recommend it, but if you really want / must, change you class definition into |
Beta Was this translation helpful? Give feedback.
-
|
SQLModel is SQLAlchemy declarative_base, so you often find the solution by searching for that instead. This SO answer is informative: https://stackoverflow.com/a/53253105 Has an example that uses SQLAlchemy-utils, based on an example there - this includes the view definition part also: class ArticleView(Base):
__table__ = create_view(
name='article_view',
selectable=sa.select(
[
Article.id,
Article.name,
User.id.label('author_id'),
User.name.label('author_name')
],
from_obj=(
Article.__table__
.join(User, Article.author_id == User.id)
)
),
metadata=Base.metadata
)There's also https://pypi.org/project/sqlalchemy-views/ but I understood that it does not have ORM support, like SQLAlchemy-utils does. Haven't tested these, we considered and it's still an option, but we now just try by filtering some queries and relationships instead as the case is pretty simple. @byrman - why would you not recommend what you say? AFAIK the solution I mentioned above boils down to the same pretty much? Maybe the lib impl there actually does more though. |
Beta Was this translation helpful? Give feedback.
-
Wasn't the question about how to do it using SQLModel on an existing view? |
Beta Was this translation helpful? Give feedback.
-
|
To clarify, I tried to map a view directly on a single |
Beta Was this translation helpful? Give feedback.
-
|
@byrman you are right, my answer is different that way - it includes both parts. AFAIK the mapping of the class to the view is:
Which I think ends up being the same as what you said:
But in my case just to a new view defined there. Maybe the lib does extra though, as there is also the Am curious about whether your solution indeed just works, or if something else is needed. And if it works, why would you not recommend it? |
Beta Was this translation helpful? Give feedback.
-
I created a view in PostgreSQL: Queried it like this: And got this output:
The latter gave me a runtime error:
Personally, I would prefer to interact with individual |
Beta Was this translation helpful? Give feedback.
-
|
Right-o, thanks for the info @byrman . We've been also happy with relationships, have not planned multi table views. We looked into using a view to implement the trashcan pattern for a kind of soft delete, like in https://michaeljswart.com/2014/04/implementing-the-recycle-bin-pattern-in-sql/ After some consideration, we didn't try views (yet), but have just now |
Beta Was this translation helpful? Give feedback.
-
|
There is this , which is maybe useful to make an SQLModel implementation not sure. I would be happy for a proper view table in SQLModel, for example for use with auto-generating migrations and hiding columns when not wanting to allow access to the underlying table. |
Beta Was this translation helpful? Give feedback.
-
|
any update on view support in sqlmodel? 👀 |
Beta Was this translation helpful? Give feedback.
-
@byrman Thank you very much! 🙏 |
Beta Was this translation helpful? Give feedback.
-
|
Another use-case is processing the results of a complex SQL query as a Python object. Sometimes quite complex SQL queries are created to extract information from numerous tables and it's not practical or feasible to repeat the same effort in SQLModel but there's a need to process the query results and having it defined as a Pydantic model really helps. |
Beta Was this translation helpful? Give feedback.
-
|
@itopaloglu83 , if you are not issuing a create statement, why does it matter if the underlying sql object is a view or a table? |
Beta Was this translation helpful? Give feedback.
-
|
@riziles , in a way it doesn't matter, it's either a complex SQL query being loaded from a text file or just querying a view. Some users just need a simple way to load the result of a query into python or Pydantic objects but it's not feasible for an ORM library to support every use-case. I personally use SQLAlchemy text statements with dataclasses as a workaround but it brings a lot of boilerplate. It is appealing to just create a view and tie that to a class and just pulling the data that way. |
Beta Was this translation helpful? Give feedback.
-
|
@itopaloglu83, I'm not sure I understand what you are saying. Why can't you use a SQLModel table on a view? This works, and presumably the user doesn't need to actually execute creates and deletes every single time they run: from typing import Optional
from sqlmodel import Field, Session, SQLModel, create_engine, select, text
class Hero(SQLModel, table=True):
name: str = Field(primary_key=True)
secret_name: str
age: Optional[int] = None
class HeroView(SQLModel, table=True):
name: str = Field(primary_key=True)
secret_name: str
age: Optional[int] = None
full_name: str
sqlite_file_name = "database.db"
sqlite_url = f"sqlite:///{sqlite_file_name}"
engine = create_engine(sqlite_url, echo=True)
def create_db_and_tables():
SQLModel.metadata.drop_all(engine, tables = [Hero.__table__])
SQLModel.metadata.create_all(engine, tables = [Hero.__table__])
with Session(engine) as session:
session.execute(text("DROP VIEW HeroView"))
session.execute(text("CREATE VIEW HeroView as select *, name || ' aka ' || secret_name as full_name from Hero"))
session.commit()
def create_heroes():
hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
with Session(engine) as session:
session.add(hero_1)
session.commit()
def select_heroes():
with Session(engine) as session:
print("adding hero2")
heroes = session.exec(select(HeroView)).all()
print(heroes)
def main():
create_db_and_tables()
create_heroes()
select_heroes()
if __name__ == "__main__":
main() |
Beta Was this translation helpful? Give feedback.
-
|
Just FYI, the use cases for views extend beyond simply joining existing models. Views are a valid tool in abstraction and, in particular, materialized views are an important performance tool. Our use case is a table that has "effective dating" of rows, but 99% of the time we only want the "current" version of something. In our case there are efficiency gains to create a That being said, it would be nice to add readonly support to a "table" model so the framework knows not to attempt to mutate it, typing hints are updated, and it's obvious to the next developer. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
First Check
Commit to Help
Example Code
Description
I have a view(Lets say HeroTeamView) created in mysql db. I want to read this. This view is essentially a left join of Hero and Teams table Joined on
Hero.Id.As shown in example above as soon as I try to select This view I get error
HeroTeamViewis not a'SQLModelMetaclass' object is not iterableI am not quiet sure I understand how to access rows created by view
Any pointers appreciated
Operating System
Windows
Operating System Details
No response
SQLModel Version
0.06
Python Version
3.9.7
Additional Context
I dont want to use Hero and Team tables directly to write a select query as there are multiple tables and joins in "real" world problem for me. Using Views provides me some obvious benefits like mentioned here
Beta Was this translation helpful? Give feedback.
All reactions