Hi Matthew It’s not an unusual approach from my standpoint. I use a combination of both ORM and Core. For my core uses, I wrote a couple of generic getter and setter methods, wrapping up a lot of boilerplate operations. In my case, it looks like this;
result = DBGetColumns(‘tableName’, [‘studentFirstname’, ‘studentSurname’], id=studentID) i.e. DBGetColumns(‘tableName’, [list of columns to return], **column:value to use in the where clause AND'ed together) It returns result dict of the column values, or None if no row is found. For my purposes, this can only be used where you expect a fetchone() result. A result array can not be returned at this time and I’ve never really needed it. In this case, the method takes the kwargs (id=studentID) and builds a where clause from it, based on the query it creates on the table. My environment has a lot of ‘built in’ context, so for example, my method can work out from it’s operating context the metadata to use to open the table. Without this context, it would look more like this; result = DBGetColumns(meta, ‘tableName’, [‘studentFirstname’, ‘studentSurname’], id=studentID) or maybe result = DBGetColumns(tableObject, [‘studentFirstname’, ‘studentSurname’], id=studentID) where tableObject is a Table() object. Of course, this is for basic selects. The where clause is always built as ‘AND’s. There’s no logic for an OR etc, and no joins. This could be done of course, but after 10 years I’ve never needed it. Finally, it can also be used to return the actual value of a single column, rather than a dict of multi columns. This is done by supplying the column name as a string, rather than a list of strings. That way, you can build robust code with inline queries very easily. e.g. if DBGetColumns(‘tableName’, ‘studentFirstname’, id=studentID) == ‘Fred’: print ‘Hi Fred' For update/insert, I have a similar method; Update existing row based on a match of the keys supplied as kwargs. In this version, if the id (kwargs) have no match, then it will raise an exception. The expectation is that you believe that studentID already exists and up want to do an update. DBSetColumns(‘tableName’, {‘studentCategory’: 1, ‘studentOtherThing’: ‘baa’}, id=studentID) Insert a new row specifically. i.e. I assume this does not exist. Logic dictates that all the mandatory columns and PK columns are included in the column dict. Note there are no kwargs. newStudentID = DBSetColumns(‘tableName’, {‘studentCategory’: 1, ‘studentOtherThing’: ‘baa’}) If I included id=studentID in the kwargs, it would attempt an update, and if it fails it performs an insert instead. You can tell be the result what it did. newID for an insert, or None if an update. Finally, returning a complete row row = DBGetRow(‘tableName’, id=studentID) Simply returns an SQLA resultRow object based on building a query on the table, applying the kwargs as a where clause and returning 1 row, or None. If there is more than one match, then the first one is returned. The assumption is that the dev uses this with an understanding of the data. I also have a function value return’er value = DBGetFuncValue(‘tableName’, function, onColumn, **kwargs) This is useful for quickly and easily getting the MAX, MIN, AVG etc of a column based on a select query. e.g. (Silly example, but you can see what I mean) if DBGetFuncValue(‘students’, ‘MAX’, ‘lastTestResult’, studentCategoryID=23) < passingGrade: print “This bunch of students all failed!" I use these literally all day every day and they have proven to be a real asset. Recently, I wanted to support a way of raising notifications (in my case adding things into a Queue.Queue() when operations happened on some tables. I simply updated the central method and it worked, even though there were 1000’s of cases where it was used. :-) With all of the above, there are some more subtle use cases that I have not really covered. e.g. If I pass in a tuple if (‘tableName’, sessionObject) then the code will do the insert/update inside a transaction for that session, rather than a direct update etc. Hope you gain some insight and inspiration. Happy to chat 1:1 if you would like more info. Cheers Warwick > On 23 Apr 2021, at 11:51 AM, mkmo...@gmail.com <mkmoi...@gmail.com> wrote: > > Hi dAll, > Some people don't like ORMs and instead use query builders like SQLAlchemy > Core (or even raw SQL text) even for something like a CRUD application. > > For sake of argument, let's put aside whether or not this is a good idea. I'm > just curious how one would go about this without copy and pasting a large > amount of functions for every table in your data model. > > For example if you had two tables, School and Student, you would probably > have functions like insert_school, insert_student, update_school, > update_student, get_school, get_student, delete_school, delete_student, and > etc. where the majority of the implementing code is the same except for the > table and field names. > > Do people who use SQLAlchemy Core as a query builder for CRUD applications > simply write out all these functions? Or do they try to create some kind of > generic function that can introspect the table? Is there another approach I > may not be considering? > > Thanks and best regards, > > Matthew Moisen > > -- > SQLAlchemy - > The Python SQL Toolkit and Object Relational Mapper > > http://www.sqlalchemy.org/ <http://www.sqlalchemy.org/> > > To post example code, please provide an MCVE: Minimal, Complete, and > Verifiable Example. See http://stackoverflow.com/help/mcve > <http://stackoverflow.com/help/mcve> for a full description. > --- > You received this message because you are subscribed to the Google Groups > "sqlalchemy" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to sqlalchemy+unsubscr...@googlegroups.com > <mailto:sqlalchemy+unsubscr...@googlegroups.com>. > To view this discussion on the web visit > https://groups.google.com/d/msgid/sqlalchemy/ab775a14-4045-49d4-946a-0adc0ef887ecn%40googlegroups.com > > <https://groups.google.com/d/msgid/sqlalchemy/ab775a14-4045-49d4-946a-0adc0ef887ecn%40googlegroups.com?utm_medium=email&utm_source=footer>. -- SQLAlchemy - The Python SQL Toolkit and Object Relational Mapper http://www.sqlalchemy.org/ To post example code, please provide an MCVE: Minimal, Complete, and Verifiable Example. See http://stackoverflow.com/help/mcve for a full description. --- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/sqlalchemy/E3920F92-FF1D-4129-AFF1-FF389FB85C62%40mushroomsys.com.