`selection()` beschreibt keine Tätigkeit und damit auch nicht was die Funktion macht.
`all` ist der Name einer (nützlichen) eingebauten Funktion. Den sollte man nicht an etwas anderes binden. Das führt zu Irritationen beim Leser. Das Argument ist ein Flag, da sollte man also nicht `None` und *irgendwas anderes* übergeben, sondern `True` und `False`.
Schliessen von Ressourcen würde ich mit ``with`` und `contextlib.closing()` erledigen (sofern das Objekt selbst kein Kontextmanager ist). Wenn man das mit dem Cursor macht, dann wird man den `row`-Namen los, weil man einfach direkt ``return`` verwenden kann.
Die beiden Zweige von dem ``if``/``else`` enden mit genau dem gleichen Code. Der sollte da also nicht zweimal stehen, sondern einmal hinter dem ``if``/``else``.
Mit vernünftigeren Namen und ``with`` könnte das dann so aussehen:
Code: Alles auswählen
def select(
result_column_name,
table_name,
column_name_1,
column_name_2,
value_1,
value_2,
fetch_all,
):
with closing(g.connection.cursor()) as cursor:
if value_2 is None:
cursor.execute(
'SELECT %s FROM %s WHERE %s = %s',
(result_column_name, table_name, column_name_1, value_1,)
)
else:
cursor.execute(
'SELECT %s FROM %s WHERE %s = %s AND %s = %s',
(
result_column_name,
table_name,
column_name_1,
value_1,
column_name_2,
value_2,
)
)
return cursor.fetchall() if fetch_all else cursor.fetchone()
Code: Alles auswählen
def select(result_column_name, table_name, names_and_values, fetch_all):
sql = 'SELECT %s FROM %s'
query_values = list()
for item in names_and_values:
query_values.extend(item)
if query_values:
sql += ' WHERE ' + ' AND '.join(['%s = %s'] * len(names_and_values))
with closing(g.connection.cursor()) as cursor:
cursor.execute(sql, query_values)
return cursor.fetchall() if fetch_all else cursor.fetchone()
Code: Alles auswählen
row = select(
'user_hashed_password',
'user',
[('user_name', request.form['logname'])],
False
)
Achtung: Die Funktion hat natürlich immer noch das Problem mit den SQL-Namen und -Werten von der Ausgangsfunktion!
Was immer noch unpraktisch ist (neben der Tatsache das die Funktion nicht funktioniert ) ist die unterschiedliche Struktur des Rückgabewerts in Abhängigkeit des letzten Arguments. Für solche APIs werden Dich andere Programmierer irgendwann anfangen zu hassen. Und da man selbst der ”andere Programmierer” ist, wenn man den Code eine Weile nicht angefasst hat, kann man das auch nicht mit „ist ja nur für mich“ abtun. Man könnte leicht zwei Funktionen schreiben und den gemeinsamen Teil in eine nicht-öffentliche Funktion auslagern:
Code: Alles auswählen
def _select(result_column_name, table_name, names_and_values, method_name):
sql = 'SELECT %s FROM %s'
query_values = list()
for item in names_and_values:
query_values.extend(item)
if query_values:
sql += ' WHERE ' + ' AND '.join(['%s = %s'] * len(names_and_values))
with closing(g.connection.cursor()) as cursor:
cursor.execute(sql, query_values)
return getattr(cursor, method_name)()
def select_one(result_column_name, table_name, names_and_values):
return _select(result_column_name, table_name, names_and_values, 'fetchone')
def select_all(result_column_name, table_name, names_and_values):
return _select(result_column_name, table_name, names_and_values, 'fetchall')
Code: Alles auswählen
cursor = g.connection.cursor()
cursor.execute(
'INSERT INTO file (file_file, file_name, file_author,'
' file_upload, file_type, data_size)'
' VALUES (%s, %s, %s, NOW(), %s, %s)',
(
data,
filename,
session['username'],
os.path.splitext(filename)[1],
len(data),
)
)
g.connection.commit()
cursor.close()
Code: Alles auswählen
g.session.add(
File(
content=data,
name=filename,
author=session['username'],
type=os.path.splitext(filename)[1],
size=len(data),
)
)
g.session.commit()
Code: Alles auswählen
pdf_files = (
g.session.query(File)
.filter(File.user_name == User.name, File.type == 'pdf')
.order_by(File.name)
.all()
)
Code: Alles auswählen
files = user.files
Code: Alles auswählen
class User(Base):
# ...
def get_files(self, file_type=None):
query = self.files_query # <- Bei Fremdschlüsselbeziehung definiert.
if file_type is not None:
query = query.filter(File.type == file_type)
return query.all()
Code: Alles auswählen
pdf_files = user.get_files('pdf')