Pony ORM做了将生成器表达式转换为SQL的好方法.例:
>>> select(p for p in Person if p.name.startswith('Paul'))
.order_by(Person.name)[:2]
SELECT "p"."id", "p"."name", "p"."age"
FROM "Person" "p"
WHERE "p"."name" LIKE "Paul%"
ORDER BY "p"."name"
LIMIT 2
[Person[3], Person[1]]
>>>
Run Code Online (Sandbox Code Playgroud)
我知道Python内置了精彩的内省和元编程,但是这个库如何能够在不进行预处理的情况下转换生成器表达式?它看起来像魔术.
[更新]
Blender写道:
这是你要追求的文件.它似乎使用一些内省魔法重建了生成器.我不确定它是否支持100%的Python语法,但这非常酷.- 搅拌机
我在想他们正在探索生成器表达式协议的一些功能,但是查看这个文件,并看到所ast涉及的模块......不,他们不是在动态检查程序源,是吗?令人兴奋...
@BrenBarn:如果我尝试在select函数调用之外调用生成器,结果是:
>>> x = (p for p in Person if p.age > 20)
>>> x.next()
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
File "<interactive input>", line 1, in <genexpr>
File "C:\Python27\lib\site-packages\pony\orm\core.py", …Run Code Online (Sandbox Code Playgroud) 说我在这里有这个简单的小POM ORM映射.从Python 3.4开始,内置的Enum类是新的,并且向后移植到2.7.
from enum import Enum
from pony.orm import Database, Required
class State(Enum):
ready = 0
running = 1
errored = 2
if __name__ == '__main__':
db = Database('sqlite', ':memory:', create_db=True)
class StateTable(db.Entity):
state = Required(State)
db.generate_mapping(create_tables=True)
Run Code Online (Sandbox Code Playgroud)
当我运行该程序时,会抛出一个错误.
TypeError: No database converter found for type <enum 'State'>
Run Code Online (Sandbox Code Playgroud)
这是因为Pony不支持映射枚举类型.当然,这里的解决方法是只存储Enum值,并在Class StateTable中提供一个getter,以便再次将值转换为Enum.但这很乏味且容易出错.我也可以使用另一个ORM.如果这个问题变得太令人头疼,也许我会的.但如果可以的话,我宁愿坚持使用Pony.
我宁愿创建一个数据库转换器来存储枚举,就像错误消息暗示一样.有谁知道如何做到这一点?
更新:感谢Ethan的帮助,我提出了以下解决方案.
from enum import Enum
from pony.orm import Database, Required, db_session
from pony.orm.dbapiprovider import StrConverter
class State(Enum):
ready = 0
running = 1
errored = 2
class EnumConverter(StrConverter):
def …Run Code Online (Sandbox Code Playgroud) 我有一个现有的MySQL数据库,我想用PonyORM来反映.
我知道我可以用SQLAlchemy做到这一点:
engine = create_engine(...)
Base = declarative_base(metadata=MetaData(bind=engine))
...
...
class MyTable(Base):
__table__ = Table('table_name', Base.metadata, autoload=True)
Run Code Online (Sandbox Code Playgroud)
是否有类似的方法与PonyORM一样?我在网站上找不到相关信息.
如果这是一个显而易见的问题,请原谅我,但我一般都是小马和数据库的新手,并没有找到回答这个问题的文档的正确部分.
我正在尝试创建一个包含公司的数据库以及这些公司设有办事处的地点.这是一种多对多的关系,因为每个公司都在多个地点,每个地点都可以托管多家公司.我正在定义我的实体:
from pony import orm
class Company(db.Entity):
'''A company entry in database'''
name = orm.PrimaryKey(str)
locations = orm.Set('Location')
class Location(db.Entity):
'''A location for a company'''
name = orm.PrimaryKey(str)
companies = orm.Set('Company')
Run Code Online (Sandbox Code Playgroud)
理想情况下,我希望能够编写一个将公司添加到数据库的功能,同时还添加该公司所在位置的列表,同时确保添加新的位置实例(如果它们尚不存在).我可以很快想到两种方法.
首先是尝试输入该位置,即使它存在并处理异常:
@orm.db_session
def add_company(name, locations):
loc_entities = []
for l in locations:
try:
loc = Location[l]
except orm.core.ObjectNotFound:
loc = Location(name=l)
else:
loc_entities.append(loc)
comp = Company(name=name, locations=loc_entities)
Run Code Online (Sandbox Code Playgroud)
第二个是查询数据库并询问这些位置是否存在:
@orm.db_session
def add_company2(name, locations):
old_loc_entities = orm.select(l for l in Location if l.name in locations)[:]
old_locations = [l.name for …Run Code Online (Sandbox Code Playgroud) 我有一个用作ORM 的flask应用程序pony.应用程序每次请求时都会逐渐增加其内存使用量.我需要测量程序不同部分的内存使用情况来发现问题.
不幸的是,由于程序没有返回执行并且一直在运行,我无法使用内存分析工具,如memory_profiler.如何分析连续运行的应用程序的内存使用情况?
我正在使用这个Python ORM来管理我的应用程序中的数据库:ponyorm.com
我只是在我的表中更改了一个属性,我会向我做一个rowcount,他返回1为TRUE,0为FALSE.
例如:仅使用sqlite3我会这样做:
user = conn.execute('SELECT * FROM users')
count = user.rowcount
if count == 1:
print('Return %d lines' %count)
else:
print('Bad....return %d lines', %count)
Run Code Online (Sandbox Code Playgroud) 很多时候,我写了如下的查询:
pony.orm.select(u for u in User if u.available and u.friends > 0 and ...)
Run Code Online (Sandbox Code Playgroud)
所以,我想编写自己的版本select,替代它.有些事情是为了避免我每次写出谓词的第一部分,if u.available and u.friends > 0.
我的问题更为笼统:如何编写一个函数,就像select它接受select方法或count方法可以接受的参数一样.
我只是想尝试一下用于小型个人 Web 应用程序的 pony orm 映射器。除了为实体定义自定义构造函数之外,一切正常。
在下面的代码中,我创建了一个带有字符串字段的简单实体name,并定义了一个构造函数,该构造函数除了将参数重定向到父构造函数之外什么也不做(在我的真实应用程序中,我在将它们传递给父构造函数之前更改了一些参数)。之后我创建一个User并打印它的名称。
from pony.orm import Database, Required, db_session, commit
db = Database("sqlite", ":memory:", create_db=True)
class User(db.Entity):
def __init__(self, *args, **kwargs):
super(User, self).__init__(*args, **kwargs)
name = Required(str)
db.generate_mapping(create_tables=True)
with db_session:
u = User(name="Admin")
commit()
print(u, u.name)
Run Code Online (Sandbox Code Playgroud)
错误消息TypeError: object.__init__() takes no parameters与调用位于同一行super()。看起来关键字参数被发送到object而不是db.Entity. 当我删除构造函数时,一切正常
那么为什么它不起作用呢。难道像我的例子中的构造函数不应该总是工作(当然什么也不做)吗?ponyorm 中是否有某些东西阻止它工作,或者我在这里遗漏了一些东西?
为了完整起见,我的实体定义实际上是这样的
class User(db.Entity):
def __init__(self, *args, **kwargs):
if "password" not in kwargs:
raise ValueError("password is required")
kwargs["password"] = werkzeug.security.generate_password_hash(kwargs["password"])
super().__init__(*args, …Run Code Online (Sandbox Code Playgroud) Python 的标准库模块 sqlite3 支持加载 sqlite 扩展,也支持全文搜索。ORM Peewee还包括支持。(两者都支持FTS3/FTS4并且 Peewee 也明确支持 FTS5。
在 Pony ORM 应用程序中,我如何最好地集成 sqlite3 的全文搜索,无论是 FTS3/FTS4 还是 FTS5?
我想原则上,我可以使用 sqlite3 模块甚至 Peewee 连接到数据库并使用它们的功能。但是,我不知道是否有任何关于并发访问数据库文件的问题。也可能更好地集成全文搜索,以便例如可以使用理解句法来完成全文搜索。
我正在尝试使用 Pony ORM 将多个值插入到我的 postgres 数据库中。我目前的方法非常低效:
from pony.orm import *
db = Database()
class Names(db.Entity):
first_name = Optional(str)
last_name = Optional(str)
family = [["Peter", "Mueller"], ["Paul", "Meyer"], ...]
@db_session
def populate_names(name_list)
for name in name_list:
db.insert("Names", first_name=name[0], last_name=name[1])
if __name__ == "__main__":
db.bind(provider='postgres', user='', password='', host='', database='')
db.generate_mappings(create_tables=True)
populate_names(family)
Run Code Online (Sandbox Code Playgroud)
这只是一个简短的示例,但输入的结构是相同的:列表列表。我从几个 xml 文件中提取数据并一次插入一个“文件”。
有没有人知道如何在 Pony ORM 中将多行数据放入一个插入查询中?
ponyorm ×10
python ×9
orm ×4
database ×2
python-2.7 ×2
python-3.x ×2
sqlite ×2
dsl ×1
enums ×1
flask ×1
mysql ×1
postgresql ×1