簡體   English   中英

我可以像這樣將python的`for`語句與SQL結合:`db.select('table_name',where ='...')中的for id,name,ctime。

[英]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

另一種方法是( SSNTCursor ,可以將其視為提供元組或字典的現有游標的替代方法。 這些新的游標還為命名為元組的行提供從結果集中提取的名稱信息。

以下示例未使用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循環,前提是該表具有idusername作為第一個字段,例如:

for userid, username, *rest in cnx.select(table='auth_user', where='id=1'):
    print(userid, username)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM