简体   繁体   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='…')`

So I'm accessing MySQL from python 2.7 scripts, now I can do this: 因此,我正在从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

But the duplicate variables id, name, area of the for statement and those in the select statement are eating me up. 但是重复的变量id, name, area for语句的id, name, area以及select语句中的变量使我吃饱了。 Assuming the db column names can be used as variable names, I want something like this: 假设数据库列名称可以用作变量名称,我想要这样的东西:

for id, name, area in db.select(from='sometable', where='area IS NOT NULL'):
    print id, name, area

Of course the variables in the for statement must be dynamically passed into db.select , so that I can change it without changing db.select . 当然,必须将for语句中的变量动态地传递到db.select ,以便我可以更改它而无需更改db.select

The one solution in the comment, suggesting to use a dictionary row factory, seems very close to what you want. 评论中的一个解决方案,建议使用字典行工厂,似乎与您想要的非常接近。

Even closer (as easier to write) seems to me a namedtuple . 在我看来,更接近(更容易写)的是一个namedtuple For this purpose, I once wrote this: 为此,我曾经这样写过:

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

With the namtupiter() , you can iterate over a cursor containing a resultset and receive NamedTuples with the DB fields contained as attributes. 使用namtupiter() ,您可以遍历包含结果集的游标,并接收包含DB域作为属性的NamedTuples。

So you can do 所以你可以做

for r in namtupiter(db.select(fields=('id', 'name', 'area', _from='sometable', where='area IS NOT NULL')):
    print r.id, r.name, r.area

Another way is the ( SS ) NTCursor which can be seen as an alternative to the existing cursors which provide tuples or dicts. 另一种方法是( SSNTCursor ,可以将其视为提供元组或字典的现有游标的替代方法。 These new cursors as well provide the rows as named tuples with the name information extracted from the result set. 这些新的游标还为命名为元组的行提供从结果集中提取的名称信息。

The following example is not using namedtuple. 以下示例未使用namedtuple。 I'm using mysql.connector, but can be done with whatever database driver: 我正在使用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()

(Careful for SQL-injection with passing WHERE-clauses like that) (通过这样的WHERE子句小心SQL注入)

With Python 3, you would be able to do the last for-loop, provided the table has id and username as first fields, like this: 使用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.

相关问题 从redshift和从python提取DB表蓝图,例如“ describe table_name” commande - Fetch DB tables blueprint like “describe table_name” commande from redshift and DB2 from python 如何避免使用“SELECT * FROM {table_name}”进行 SQL 注入? - How to avoid SQL injection with “SELECT * FROM {table_name}”? MySql SELECT * FROM table_name WHERE col_name IN(任何值) - MySql SELECT * FROM table_name WHERE col_name IN (any value) select_from(table_name)中的table_name是什么类型? - What is the type of table_name in select_from(table_name)? 选择名称,其中id =“在python列表中”? - select name where id = “in the python list”? python sql,“选择? 从表在哪里? 像?”,(选择,在哪里,像) - python sql, “select ? from table where ? like ?”,(selected,where,like)) SELECT * FROM table_name仅给我一列作为结果 - SELECT * FROM table_name give me only one column as result 我怎么能 SELECT FROM sqlite3_table WHERE column_name IN variable tuple? - how can i SELECT FROM sqlite3_table WHERE column_name IN variable tuple? 我可以为 Python 中的变量分配 ID/名称吗? - Can I assign an ID/Name to a variable in Python? 我可以在 Python 中合并多个具有相同名称的字典吗? - Can I combine multiple dicts with the same name in Python?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM