[英]Fetch DB tables blueprint like “describe table_name” commande from redshift and DB2 from python
[英]Can I combine python's `for` statement with SQL like this: `for id, name, ctime in db.select('table_name', where='…')`
因此,我正在從python 2.7腳本訪問MySQL,現在可以執行以下操作:
for id, name, area in db.select('SELECT id, name, area'
' FROM some_table'
' WHERE area IS NOT NULL'):
print id, name, area
但是重復的變量id, name, area
for語句的id, name, area
以及select語句中的變量使我吃飽了。 假設數據庫列名稱可以用作變量名稱,我想要這樣的東西:
for id, name, area in db.select(from='sometable', where='area IS NOT NULL'):
print id, name, area
當然,必須將for語句中的變量動態地傳遞到db.select
,以便我可以更改它而無需更改db.select
。
評論中的一個解決方案,建議使用字典行工廠,似乎與您想要的非常接近。
在我看來,更接近(更容易寫)的是一個namedtuple
。 為此,我曾經這樣寫過:
def namtupiter(c):
from collections import namedtuple
fields = tuple(i[0] for i in c.description)
Row = namedtuple('Row', fields)
# make Row a tuple and a "dict" (well, kind of...) at the same time.
# Don't lose tuple property, so only process strings and pass everything
# other to super().
Row.__getitem__ = lambda self, item: getattr(self, item) if isinstance(item, basestring) else super(Row, self).__getitem__(item)
for i in c:
try:
# try to access i as a dict
yield Row(*(i[f] for f in fields))
except TypeError:
# it is no dict -> try tuple
yield Row(*i)
class CursorNTRowsMixIn(object):
_fetch_type = 0 # tuples
def _do_get_result(self):
super(CursorNTRowsMixIn, self)._do_get_result()
# create a named tuple class
from collections import namedtuple
if self.description:
self.RowClass = namedtuple('Row', tuple(i[0] for i in self.description))
def _fetch_row(self, size=1):
rows = super(CursorNTRowsMixIn, self)._fetch_row(size)
# turn every row into a Row().
return tuple(self.RowClass(*i) for i in rows)
class NTCursor(CursorStoreResultMixIn, CursorNTRowsMixIn,
BaseCursor):
pass
class SSNTCursor(CursorUseResultMixIn, CursorNTRowsMixIn,
BaseCursor):
pass
使用namtupiter()
,您可以遍歷包含結果集的游標,並接收包含DB域作為屬性的NamedTuples。
所以你可以做
for r in namtupiter(db.select(fields=('id', 'name', 'area', _from='sometable', where='area IS NOT NULL')):
print r.id, r.name, r.area
另一種方法是( SS
) NTCursor
,可以將其視為提供元組或字典的現有游標的替代方法。 這些新的游標還為命名為元組的行提供從結果集中提取的名稱信息。
以下示例未使用namedtuple。 我正在使用mysql.connector,但是可以使用任何數據庫驅動程序來完成:
import mysql.connector
CONFIG = {
'database': 'test',
'user': 'root',
}
class MySQLStackOverflowConnect(mysql.connector.MySQLConnection):
def select(self, table, where, fields=None):
if isinstance(fields, (list, tuple)):
select_fields = ', '.join(fields)
else:
select_fields = '*'
query = "SELECT {fields} FROM `{table}` WHERE {where}".format(
table=table, where=where, fields=select_fields)
cur = self.cursor(buffered=True)
cur.execute(query)
return cur
cnx = MySQLStackOverflowConnect(**CONFIG)
for userid, username in cnx.select(table='users', where='id=1',
fields=('id', 'username')):
print userid, username
cnx.close()
(通過這樣的WHERE子句小心SQL注入)
使用Python 3,您可以執行最后一個for循環,前提是該表具有id
和username
作為第一個字段,例如:
for userid, username, *rest in cnx.select(table='auth_user', where='id=1'):
print(userid, username)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.