Reputation: 517
Please tell me how to select and manipulate rows from a VIEW similarly to how I use SQLAlchemy on a TABLE.
Here's how I would do the query if name_address_vw were a table (Engine already set up using JDBC Psycopg2 to a PostgreSQL database and not shown):
meta = MetaData(Engine,reflect=True)
nav = meta.tables['name_address_vw']
Session = sessionmaker(bind=engine)
session = Session()
navRow = session.query(
nav
).filter(
nav.c.address.like("%pad%")
).first()
print (navRow.name)
SQLAlchemy fails because name_address_vw is not a key member of meta.tables I understand this is because it is a view, not a table.
Here are the SQL statements to set up and populate the backend PostgreSQL:
CREATE TABLE name
(
id SERIAL PRIMARY KEY,
name VARCHAR NOT NULL
);
CREATE TABLE address
(
id SERIAL PRIMARY KEY,
idA INTEGER REFERENCES name(id),
address VARCHAR
);
CREATE VIEW name_address_vw AS SELECT
A.id,
A.name,
B.address
FROM name A
LEFT JOIN address B ON A.id = B.idA;
INSERT INTO name(
id, name)
VALUES
(1, 'John Soap'),
(2, 'Jane Doe');
INSERT INTO address(
id, idA, address)
VALUES
(1, 1, 'John''s place'),
(2, 2, 'Jane''s pad');
In case my SQLAlchemy code above is unclear, here is the PostreSQL query equivalent:
SELECT name FROM name_address_vw WHERE address LIKE '%pad%' LIMIT 1;
The example I have given is highly simplified and I need to be able to query other columns on the view rows once I have retrieved them, so please provide me with a general solution rather than one that works solely with this example—many thanks.
Upvotes: 7
Views: 11008
Reputation: 66
Since 2.0 binding the Metadata object to an Engine is deprecated, the correct way would be:
meta = MetaData()
meta.reflect(bind=Engine, views=True)
nav = meta.tables['name_address_vw']
Link to doc: https://docs.sqlalchemy.org/en/14/changelog/migration_20.html#implicit-and-connectionless-execution-bound-metadata-removed .
Upvotes: 3
Reputation: 52929
The use of reflect
parameter of MetaData
has been deprecated since version 0.8 and should be replaced with the more expressive MetaData.reflect()
method, which allows reflecting views as well:
meta = MetaData(Engine)
meta.reflect(views=True)
nav = meta.tables['name_address_vw']
Upvotes: 15