如何在不编写SQL的情况下在python中使用SQL数据库?

时间:2015-12-29 04:24:51

标签: python sql sqlite orm

我正在寻找一种在python中使用SQL数据库(如MySQL,SQLite)而不实际编写SQL的方法。示例将是这样的(伪代码):

# INSERT INTO table (firstname, lastname) VALUES ('John', 'Smith')
table.insert({'firstname':'John', 'lastname':'Smith'})

# SELECT * FROM table WHERE name='John'
results = table.select({'firstname': 'John'})
print results
# [ {'firstname':'John', 'lastname':'Smith'} ]

围绕python的DB-API,或者可能是非常轻量级ORM的光包装,可以完成这项工作。如果它是一个ORM,它应该允许将namedtuple映射到DB,因为这几乎是我想要使用的唯一类型的对象。我确信这样的事情已经存在,但我很难找到它:)

编辑有些建议的解决方案并非我的想法:

SQL Alchemy

好:插入和选择相当简洁

坏:存储和检索的对象不是普通的python dicts / namedtuples / whatever(可能它们可以被命名为theupuples,但它们并不明显如何)

丑陋:必须明确地为每个表创建一个类,这使得它太重量级了

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, Sequence('user_id_seq'), primary_key=True)
    name = Column(String(50))
    fullname = Column(String(50))
    ...

ed_user = User(name='ed', fullname='Ed Jones', password='edspassword')
session.add(ed_user)

our_user = session.query(User).filter_by(name='ed').first() 
our_user
<User(name='ed', fullname='Ed Jones', password='edspassword')>

PonyORM

好:将查询作为生成器编写的方式是纯粹的天才

坏:仍然使用自定义对象,而不是内置python数据类型

丑陋:与SQL Alchemy一样,需要为每个表创建一个类

from pony.orm import *

db = Database()
class Person(db.Entity):
    name = Required(str)
    age = Required(int)

p1 = Person(name='John', age=20)
commit()

persons = select(p for p in Person if p.age > 20)

2 个答案:

答案 0 :(得分:4)

您只需要做一些工作 - 阅读文档。 SQLAlchemy可能是最简单的“数据库逆向工程”(称为反射),详细here

最简单的例子:

from sqlalchemy import *

metadata = MetaData()
engine = create_engine('mysql+mysqldb://scott:tiger@localhost/foo')
person_table = Table('person', metadata, autoload=True, autoload_with_engine=engine)
q = person_table.insert().values(name='John', age=20)
connection = engine.connect()
connection.execute(q)

答案 1 :(得分:1)

dataset库是您问题的很好答案

示例:

import dataset

db = dataset.connect('sqlite:///:memory:')

table = db['sometable']
table.insert(dict(name='John Doe', age=37))
table.insert(dict(name='Jane Doe', age=34, gender='female'))

john = table.find_one(name='John Doe')