Working with Joins

SQLAlchemy ORM – Working with Joins ”; Previous Next Now that we have two tables, we will see how to create queries on both tables at the same time. To construct a simple implicit join between Customer and Invoice, we can use Query.filter() to equate their related columns together. Below, we load the Customer and Invoice entities at once using this method − from sqlalchemy.orm import sessionmaker Session = sessionmaker(bind = engine) session = Session() for c, i in session.query(Customer, Invoice).filter(Customer.id == Invoice.custid).all(): print (“ID: {} Name: {} Invoice No: {} Amount: {}”.format(c.id,c.name, i.invno, i.amount)) The SQL expression emitted by SQLAlchemy is as follows − SELECT customers.id AS customers_id, customers.name AS customers_name, customers.address AS customers_address, customers.email AS customers_email, invoices.id AS invoices_id, invoices.custid AS invoices_custid, invoices.invno AS invoices_invno, invoices.amount AS invoices_amount FROM customers, invoices WHERE customers.id = invoices.custid And the result of the above lines of code is as follows − ID: 2 Name: Gopal Krishna Invoice No: 10 Amount: 15000 ID: 2 Name: Gopal Krishna Invoice No: 14 Amount: 3850 ID: 3 Name: Govind Pant Invoice No: 3 Amount: 10000 ID: 3 Name: Govind Pant Invoice No: 4 Amount: 5000 ID: 4 Name: Govind Kala Invoice No: 7 Amount: 12000 ID: 4 Name: Govind Kala Invoice No: 8 Amount: 8500 ID: 5 Name: Abdul Rahman Invoice No: 9 Amount: 15000 ID: 5 Name: Abdul Rahman Invoice No: 11 Amount: 6000 The actual SQL JOIN syntax is easily achieved using the Query.join() method as follows − session.query(Customer).join(Invoice).filter(Invoice.amount == 8500).all() The SQL expression for join will be displayed on the console − SELECT customers.id AS customers_id, customers.name AS customers_name, customers.address AS customers_address, customers.email AS customers_email FROM customers JOIN invoices ON customers.id = invoices.custid WHERE invoices.amount = ? We can iterate through the result using for loop − result = session.query(Customer).join(Invoice).filter(Invoice.amount == 8500) for row in result: for inv in row.invoices: print (row.id, row.name, inv.invno, inv.amount) With 8500 as the bind parameter, following output is displayed − 4 Govind Kala 8 8500 Query.join() knows how to join between these tables because there’s only one foreign key between them. If there were no foreign keys, or more foreign keys, Query.join() works better when one of the following forms are used − query.join(Invoice, id == Address.custid) explicit condition query.join(Customer.invoices) specify relationship from left to right query.join(Invoice, Customer.invoices) same, with explicit target query.join(”invoices”) same, using a string Similarly outerjoin() function is available to achieve left outer join. query.outerjoin(Customer.invoices) The subquery() method produces a SQL expression representing SELECT statement embedded within an alias. from sqlalchemy.sql import func stmt = session.query( Invoice.custid, func.count(”*”).label(”invoice_count”) ).group_by(Invoice.custid).subquery() The stmt object will contain a SQL statement as below − SELECT invoices.custid, count(:count_1) AS invoice_count FROM invoices GROUP BY invoices.custid Once we have our statement, it behaves like a Table construct. The columns on the statement are accessible through an attribute called c as shown in the below code − for u, count in session.query(Customer, stmt.c.invoice_count).outerjoin(stmt, Customer.id == stmt.c.custid).order_by(Customer.id): print(u.name, count) The above for loop displays name-wise count of invoices as follows − Arjun Pandit None Gopal Krishna 2 Govind Pant 2 Govind Kala 2 Abdul Rahman 2 Print Page Previous Next Advertisements ”;

Eager Loading

SQLAlchemy ORM – Eager Loading ”; Previous Next Eager load reduces the number of queries. SQLAlchemy offers eager loading functions invoked via query options which give additional instructions to the Query. These options determine how to load various attributes via the Query.options() method. Subquery Load We want that Customer.invoices should load eagerly. The orm.subqueryload() option gives a second SELECT statement that fully loads the collections associated with the results just loaded. The name “subquery” causes the SELECT statement to be constructed directly via the Query re-used and embedded as a subquery into a SELECT against the related table. from sqlalchemy.orm import subqueryload c1 = session.query(Customer).options(subqueryload(Customer.invoices)).filter_by(name = ”Govind Pant”).one() This results in the following two SQL expressions − SELECT customers.id AS customers_id, customers.name AS customers_name, customers.address AS customers_address, customers.email AS customers_email FROM customers WHERE customers.name = ? (”Govind Pant”,) SELECT invoices.id AS invoices_id, invoices.custid AS invoices_custid, invoices.invno AS invoices_invno, invoices.amount AS invoices_amount, anon_1.customers_id AS anon_1_customers_id FROM ( SELECT customers.id AS customers_id FROM customers WHERE customers.name = ?) AS anon_1 JOIN invoices ON anon_1.customers_id = invoices.custid ORDER BY anon_1.customers_id, invoices.id 2018-06-25 18:24:47,479 INFO sqlalchemy.engine.base.Engine (”Govind Pant”,) To access the data from two tables, we can use the below program − print (c1.name, c1.address, c1.email) for x in c1.invoices: print (“Invoice no : {}, Amount : {}”.format(x.invno, x.amount)) The output of the above program is as follows − Govind Pant Gulmandi Aurangabad [email protected] Invoice no : 3, Amount : 10000 Invoice no : 4, Amount : 5000 Joined Load The other function is called orm.joinedload(). This emits a LEFT OUTER JOIN. Lead object as well as the related object or collection is loaded in one step. from sqlalchemy.orm import joinedload c1 = session.query(Customer).options(joinedload(Customer.invoices)).filter_by(name=”Govind Pant”).one() This emits following expression giving same output as above − SELECT customers.id AS customers_id, customers.name AS customers_name, customers.address AS customers_address, customers.email AS customers_email, invoices_1.id AS invoices_1_id, invoices_1.custid AS invoices_1_custid, invoices_1.invno AS invoices_1_invno, invoices_1.amount AS invoices_1_amount FROM customers LEFT OUTER JOIN invoices AS invoices_1 ON customers.id = invoices_1.custid WHERE customers.name = ? ORDER BY invoices_1.id (”Govind Pant”,) The OUTER JOIN resulted in two rows, but it gives one instance of Customer back. This is because Query applies a “uniquing” strategy, based on object identity, to the returned entities. Joined eager loading can be applied without affecting the query results. The subqueryload() is more appropriate for loading related collections while joinedload() is better suited for many-to-one relationship. Print Page Previous Next Advertisements ”;

Using Query

SQLAlchemy ORM – Using Query ”; Previous Next All SELECT statements generated by SQLAlchemy ORM are constructed by Query object. It provides a generative interface, hence successive calls return a new Query object, a copy of the former with additional criteria and options associated with it. Query objects are initially generated using the query() method of the Session as follows − q = session.query(mapped class) Following statement is also equivalent to the above given statement − q = Query(mappedClass, session) The query object has all() method which returns a resultset in the form of list of objects. If we execute it on our customers table − result = session.query(Customers).all() This statement is effectively equivalent to following SQL expression − SELECT customers.id AS customers_id, customers.name AS customers_name, customers.address AS customers_address, customers.email AS customers_email FROM customers The result object can be traversed using For loop as below to obtain all records in underlying customers table. Here is the complete code to display all records in Customers table − from sqlalchemy import Column, Integer, String from sqlalchemy import create_engine engine = create_engine(”sqlite:///sales.db”, echo = True) from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class Customers(Base): __tablename__ = ”customers” id = Column(Integer, primary_key = True) name = Column(String) address = Column(String) email = Column(String) from sqlalchemy.orm import sessionmaker Session = sessionmaker(bind = engine) session = Session() result = session.query(Customers).all() for row in result: print (“Name: “,row.name, “Address:”,row.address, “Email:”,row.email) Python console shows list of records as below − Name: Ravi Kumar Address: Station Road Nanded Email: [email protected] Name: Komal Pande Address: Koti, Hyderabad Email: [email protected] Name: Rajender Nath Address: Sector 40, Gurgaon Email: [email protected] Name: S.M.Krishna Address: Budhwar Peth, Pune Email: [email protected] The Query object also has following useful methods − Sr.No. Method & Description 1 add_columns() It adds one or more column expressions to the list of result columns to be returned. 2 add_entity() It adds a mapped entity to the list of result columns to be returned. 3 count() It returns a count of rows this Query would return. 4 delete() It performs a bulk delete query. Deletes rows matched by this query from the database. 5 distinct() It applies a DISTINCT clause to the query and return the newly resulting Query. 6 filter() It applies the given filtering criterion to a copy of this Query, using SQL expressions. 7 first() It returns the first result of this Query or None if the result doesn’t contain any row. 8 get() It returns an instance based on the given primary key identifier providing direct access to the identity map of the owning Session. 9 group_by() It applies one or more GROUP BY criterion to the query and return the newly resulting Query 10 join() It creates a SQL JOIN against this Query object’s criterion and apply generatively, returning the newly resulting Query. 11 one() It returns exactly one result or raise an exception. 12 order_by() It applies one or more ORDER BY criterion to the query and returns the newly resulting Query. 13 update() It performs a bulk update query and updates rows matched by this query in the database. Print Page Previous Next Advertisements ”;

Applying Filter

SQLAlchemy ORM – Applying Filter ”; Previous Next In this chapter, we will discuss how to apply filter and also certain filter operations along with their codes. Resultset represented by Query object can be subjected to certain criteria by using filter() method. The general usage of filter method is as follows − session.query(class).filter(criteria) In the following example, resultset obtained by SELECT query on Customers table is filtered by a condition, (ID>2) − result = session.query(Customers).filter(Customers.id>2) This statement will translate into following SQL expression − SELECT customers.id AS customers_id, customers.name AS customers_name, customers.address AS customers_address, customers.email AS customers_email FROM customers WHERE customers.id > ? Since the bound parameter (?) is given as 2, only those rows with ID column>2 will be displayed. The complete code is given below − from sqlalchemy import Column, Integer, String from sqlalchemy import create_engine engine = create_engine(”sqlite:///sales.db”, echo = True) from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class Customers(Base): __tablename__ = ”customers” id = Column(Integer, primary_key = True) name = Column(String) address = Column(String) email = Column(String) from sqlalchemy.orm import sessionmaker Session = sessionmaker(bind = engine) session = Session() result = session.query(Customers).filter(Customers.id>2) for row in result: print (“ID:”, row.id, “Name: “,row.name, “Address:”,row.address, “Email:”,row.email) The output displayed in the Python console is as follows − ID: 3 Name: Rajender Nath Address: Sector 40, Gurgaon Email: [email protected] ID: 4 Name: S.M.Krishna Address: Budhwar Peth, Pune Email: [email protected] Print Page Previous Next Advertisements ”;

Building Relationship

SQLAlchemy ORM – Building Relationship ”; Previous Next This session describes creation of another table which is related to already existing one in our database. The customers table contains master data of customers. We now need to create invoices table which may have any number of invoices belonging to a customer. This is a case of one to many relationships. Using declarative, we define this table along with its mapped class, Invoices as given below − from sqlalchemy import create_engine, ForeignKey, Column, Integer, String engine = create_engine(”sqlite:///sales.db”, echo = True) from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() from sqlalchemy.orm import relationship class Customer(Base): __tablename__ = ”customers” id = Column(Integer, primary_key = True) name = Column(String) address = Column(String) email = Column(String) class Invoice(Base): __tablename__ = ”invoices” id = Column(Integer, primary_key = True) custid = Column(Integer, ForeignKey(”customers.id”)) invno = Column(Integer) amount = Column(Integer) customer = relationship(“Customer”, back_populates = “invoices”) Customer.invoices = relationship(“Invoice”, order_by = Invoice.id, back_populates = “customer”) Base.metadata.create_all(engine) This will send a CREATE TABLE query to SQLite engine as below − CREATE TABLE invoices ( id INTEGER NOT NULL, custid INTEGER, invno INTEGER, amount INTEGER, PRIMARY KEY (id), FOREIGN KEY(custid) REFERENCES customers (id) ) We can check that new table is created in sales.db with the help of SQLiteStudio tool. Invoices class applies ForeignKey construct on custid attribute. This directive indicates that values in this column should be constrained to be values present in id column in customers table. This is a core feature of relational databases, and is the “glue” that transforms unconnected collection of tables to have rich overlapping relationships. A second directive, known as relationship(), tells the ORM that the Invoice class should be linked to the Customer class using the attribute Invoice.customer. The relationship() uses the foreign key relationships between the two tables to determine the nature of this linkage, determining that it is many to one. An additional relationship() directive is placed on the Customer mapped class under the attribute Customer.invoices. The parameter relationship.back_populates is assigned to refer to the complementary attribute names, so that each relationship() can make intelligent decision about the same relationship as expressed in reverse. On one side, Invoices.customer refers to Invoices instance, and on the other side, Customer.invoices refers to a list of Customers instances. The relationship function is a part of Relationship API of SQLAlchemy ORM package. It provides a relationship between two mapped classes. This corresponds to a parent-child or associative table relationship. Following are the basic Relationship Patterns found − One To Many A One to Many relationship refers to parent with the help of a foreign key on the child table. relationship() is then specified on the parent, as referencing a collection of items represented by the child. The relationship.back_populates parameter is used to establish a bidirectional relationship in one-to-many, where the “reverse” side is a many to one. Many To One On the other hand, Many to One relationship places a foreign key in the parent table to refer to the child. relationship() is declared on the parent, where a new scalar-holding attribute will be created. Here again the relationship.back_populates parameter is used for Bidirectionalbehaviour. One To One One To One relationship is essentially a bidirectional relationship in nature. The uselist flag indicates the placement of a scalar attribute instead of a collection on the “many” side of the relationship. To convert one-to-many into one-to-one type of relation, set uselist parameter to false. Many To Many Many to Many relationship is established by adding an association table related to two classes by defining attributes with their foreign keys. It is indicated by the secondary argument to relationship(). Usually, the Table uses the MetaData object associated with the declarative base class, so that the ForeignKey directives can locate the remote tables with which to link. The relationship.back_populates parameter for each relationship() establishes a bidirectional relationship. Both sides of the relationship contain a collection. Print Page Previous Next Advertisements ”;

Updating Objects

SQLAlchemy ORM – Updating Objects ”; Previous Next In this chapter, we will see how to modify or update the table with desired values. To modify data of a certain attribute of any object, we have to assign new value to it and commit the changes to make the change persistent. Let us fetch an object from the table whose primary key identifier, in our Customers table with ID=2. We can use get() method of session as follows − x = session.query(Customers).get(2) We can display contents of the selected object with the below given code − print (“Name: “, x.name, “Address:”, x.address, “Email:”, x.email) From our customers table, following output should be displayed − Name: Komal Pande Address: Koti, Hyderabad Email: [email protected] Now we need to update the Address field by assigning new value as given below − x.address = ”Banjara Hills Secunderabad” session.commit() The change will be persistently reflected in the database. Now we fetch object corresponding to first row in the table by using first() method as follows − x = session.query(Customers).first() This will execute following SQL expression − SELECT customers.id AS customers_id, customers.name AS customers_name, customers.address AS customers_address, customers.email AS customers_email FROM customers LIMIT ? OFFSET ? The bound parameters will be LIMIT = 1 and OFFSET = 0 respectively which means first row will be selected. print (“Name: “, x.name, “Address:”, x.address, “Email:”, x.email) Now, the output for the above code displaying the first row is as follows − Name: Ravi Kumar Address: Station Road Nanded Email: [email protected] Now change name attribute and display the contents using the below code − x.name = ”Ravi Shrivastava” print (“Name: “, x.name, “Address:”, x.address, “Email:”, x.email) The output of the above code is − Name: Ravi Shrivastava Address: Station Road Nanded Email: [email protected] Even though the change is displayed, it is not committed. You can retain the earlier persistent position by using rollback() method with the code below. session.rollback() print (“Name: “, x.name, “Address:”, x.address, “Email:”, x.email) Original contents of first record will be displayed. For bulk updates, we shall use update() method of the Query object. Let us try and give a prefix, ‘Mr.’ to name in each row (except ID = 2). The corresponding update() statement is as follows − session.query(Customers).filter(Customers.id! = 2). update({Customers.name:”Mr.”+Customers.name}, synchronize_session = False) The update() method requires two parameters as follows − A dictionary of key-values with key being the attribute to be updated, and value being the new contents of attribute. synchronize_session attribute mentioning the strategy to update attributes in the session. Valid values are false: for not synchronizing the session, fetch: performs a select query before the update to find objects that are matched by the update query; and evaluate: evaluate criteria on objects in the session. Three out of 4 rows in the table will have name prefixed with ‘Mr.’ However, the changes are not committed and hence will not be reflected in the table view of SQLiteStudio. It will be refreshed only when we commit the session. Print Page Previous Next Advertisements ”;

Returning List and Scalars

Returning List and Scalars ”; Previous Next There are a number of methods of Query object that immediately issue SQL and return a value containing loaded database results. Here’s a brief rundown of returning list and scalars − all() It returns a list. Given below is the line of code for all() function. session.query(Customers).all() Python console displays following SQL expression emitted − SELECT customers.id AS customers_id, customers.name AS customers_name, customers.address AS customers_address, customers.email AS customers_email FROM customers first() It applies a limit of one and returns the first result as a scalar. SELECT customers.id AS customers_id, customers.name AS customers_name, customers.address AS customers_address, customers.email AS customers_email FROM customers LIMIT ? OFFSET ? The bound parameters for LIMIT is 1 and for OFFSET is 0. one() This command fully fetches all rows, and if there is not exactly one object identity or composite row present in the result, it raises an error. session.query(Customers).one() With multiple rows found − MultipleResultsFound: Multiple rows were found for one() With no rows found − NoResultFound: No row was found for one() The one() method is useful for systems that expect to handle “no items found” versus “multiple items found” differently. scalar() It invokes the one() method, and upon success returns the first column of the row as follows − session.query(Customers).filter(Customers.id == 3).scalar() This generates following SQL statement − SELECT customers.id AS customers_id, customers.name AS customers_name, customers.address AS customers_address, customers.email AS customers_email FROM customers WHERE customers.id = ? Print Page Previous Next Advertisements ”;

Declaring Mapping

SQLAlchemy ORM – Declaring Mapping ”; Previous Next The main objective of the Object Relational Mapper API of SQLAlchemy is to facilitate associating user-defined Python classes with database tables, and objects of those classes with rows in their corresponding tables. Changes in states of objects and rows are synchronously matched with each other. SQLAlchemy enables expressing database queries in terms of user defined classes and their defined relationships. The ORM is constructed on top of the SQL Expression Language. It is a high level and abstracted pattern of usage. In fact, ORM is an applied usage of the Expression Language. Although a successful application may be constructed using the Object Relational Mapper exclusively, sometimes an application constructed with the ORM may use the Expression Language directly where specific database interactions are required. Declare Mapping First of all, create_engine() function is called to set up an engine object which is subsequently used to perform SQL operations. The function has two arguments, one is the name of database and other is an echo parameter when set to True will generate the activity log. If it doesn’t exist, the database will be created. In the following example, a SQLite database is created. from sqlalchemy import create_engine engine = create_engine(”sqlite:///sales.db”, echo = True) The Engine establishes a real DBAPI connection to the database when a method like Engine.execute() or Engine.connect() is called. It is then used to emit the SQLORM which does not use the Engine directly; instead, it is used behind the scenes by the ORM. In case of ORM, the configurational process starts by describing the database tables and then by defining classes which will be mapped to those tables. In SQLAlchemy, these two tasks are performed together. This is done by using Declarative system; the classes created include directives to describe the actual database table they are mapped to. A base class stores a catlog of classes and mapped tables in the Declarative system. This is called as the declarative base class. There will be usually just one instance of this base in a commonly imported module. The declarative_base() function is used to create base class. This function is defined in sqlalchemy.ext.declarative module. from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() Once base classis declared, any number of mapped classes can be defined in terms of it. Following code defines a Customer’s class. It contains the table to be mapped to, and names and datatypes of columns in it. class Customers(Base): __tablename__ = ”customers” id = Column(Integer, primary_key = True) name = Column(String) address = Column(String) email = Column(String) A class in Declarative must have a __tablename__ attribute, and at least one Column which is part of a primary key. Declarative replaces all the Column objects with special Python accessors known as descriptors. This process is known as instrumentation which provides the means to refer to the table in a SQL context and enables persisting and loading the values of columns from the database. This mapped class like a normal Python class has attributes and methods as per the requirement. The information about class in Declarative system, is called as table metadata. SQLAlchemy uses Table object to represent this information for a specific table created by Declarative. The Table object is created according to the specifications, and is associated with the class by constructing a Mapper object. This mapper object is not directly used but is used internally as interface between mapped class and table. Each Table object is a member of larger collection known as MetaData and this object is available using the .metadata attribute of declarative base class. The MetaData.create_all() method is, passing in our Engine as a source of database connectivity. For all tables that haven’t been created yet, it issues CREATE TABLE statements to the database. Base.metadata.create_all(engine) The complete script to create a database and a table, and to map Python class is given below − from sqlalchemy import Column, Integer, String from sqlalchemy import create_engine engine = create_engine(”sqlite:///sales.db”, echo = True) from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class Customers(Base): __tablename__ = ”customers” id = Column(Integer, primary_key=True) name = Column(String) address = Column(String) email = Column(String) Base.metadata.create_all(engine) When executed, Python console will echo following SQL expression being executed − CREATE TABLE customers ( id INTEGER NOT NULL, name VARCHAR, address VARCHAR, email VARCHAR, PRIMARY KEY (id) ) If we open the Sales.db using SQLiteStudio graphic tool, it shows customers table inside it with above mentioned structure. Print Page Previous Next Advertisements ”;

Creating Session

SQLAlchemy ORM – Creating Session ”; Previous Next In order to interact with the database, we need to obtain its handle. A session object is the handle to database. Session class is defined using sessionmaker() – a configurable session factory method which is bound to the engine object created earlier. from sqlalchemy.orm import sessionmaker Session = sessionmaker(bind = engine) The session object is then set up using its default constructor as follows − session = Session() Some of the frequently required methods of session class are listed below − Sr.No. Method & Description 1 begin() begins a transaction on this session 2 add() places an object in the session. Its state is persisted in the database on next flush operation 3 add_all() adds a collection of objects to the session 4 commit() flushes all items and any transaction in progress 5 delete() marks a transaction as deleted 6 execute() executes a SQL expression 7 expire() marks attributes of an instance as out of date 8 flush() flushes all object changes to the database 9 invalidate() closes the session using connection invalidation 10 rollback() rolls back the current transaction in progress 11 close() Closes current session by clearing all items and ending any transaction in progress Print Page Previous Next Advertisements ”;

Using Functions

SQLAlchemy Core – Using Functions ”; Previous Next Some of the important functions used in SQLAlchemy are discussed in this chapter. Standard SQL has recommended many functions which are implemented by most dialects. They return a single value based on the arguments passed to it. Some SQL functions take columns as arguments whereas some are generic. Thefunc keyword in SQLAlchemy API is used to generate these functions. In SQL, now() is a generic function. Following statements renders the now() function using func − from sqlalchemy.sql import func result = conn.execute(select([func.now()])) print (result.fetchone()) Sample result of above code may be as shown below − (datetime.datetime(2018, 6, 16, 6, 4, 40),) On the other hand, count() function which returns number of rows selected from a table, is rendered by following usage of func − from sqlalchemy.sql import func result = conn.execute(select([func.count(students.c.id)])) print (result.fetchone()) From the above code, count of number of rows in students table will be fetched. Some built-in SQL functions are demonstrated using Employee table with following data − ID Name Marks 1 Kamal 56 2 Fernandez 85 3 Sunil 62 4 Bhaskar 76 The max() function is implemented by following usage of func from SQLAlchemy which will result in 85, the total maximum marks obtained − from sqlalchemy.sql import func result = conn.execute(select([func.max(employee.c.marks)])) print (result.fetchone()) Similarly, min() function that will return 56, minimum marks, will be rendered by following code − from sqlalchemy.sql import func result = conn.execute(select([func.min(employee.c.marks)])) print (result.fetchone()) So, the AVG() function can also be implemented by using the below code − from sqlalchemy.sql import func result = conn.execute(select([func.avg(employee.c.marks)])) print (result.fetchone()) Functions are normally used in the columns clause of a select statement. They can also be given label as well as a type. A label to function allows the result to be targeted in a result row based on a string name, and a type is required when you need result-set processing to occur.from sqlalchemy.sql import func result = conn.execute(select([func.max(students.c.lastname).label(”Name”)])) print (result.fetchone()) Print Page Previous Next Advertisements ”;