我正在尝试使用 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 中将多行数据放入一个插入查询中?
在Pony ORM中,可以"自动"创建多对多关系.例如,从文档(对于版本0.6,强调我的):
要创建多对多关系,您需要将关系的两端定义为Set属性:
Run Code Online (Sandbox Code Playgroud)class Product(db.Entity): tags = Set("Tag") class Tag(db.Entity): products = Set(Product)为了在数据库中实现这种关系,Pony将创建一个中间表.这是一个众所周知的解决方案,它允许您在关系数据库中拥有多对多关系.
是否可以在自动创建的中间表中创建额外的属性(列),因此不仅仅是"产品"和"标签"的外键,还有例如时间戳?
如果有,怎么样?
如果没有,我想我必须明确地创建中间表.在这种情况下,我仍然可以使用nice Set-attribute定义(可能是中间表,指示感兴趣的属性)?
pony.orm.core.TransactionError: An attempt to mix objects belonging to different transactions
我知道这个错误是描述性的,我只是不明白为什么会发生。我搜索了谷歌、文档、其他帖子,但什么也没找到。
有任何想法吗?
我想将我的模型类分离到models目录中的单独文件中。我想要一个单独的文件用于:
我不确定如何组织我的项目来实现这一目标。
我尝试将主要导入文件放入目录的init .py中,并将它们导入各个模型文件中,但是我不知道将db.generate_mapping()放在哪里,以便所有类都可用。我猜想这是大型应用程序的最佳实践。此时,我的应用程序中大约有150张桌子。
任何帮助/指针将不胜感激。
代码非常简单,如下所示:
from pony.orm import Required, Set, Optional, PrimaryKey
from pony.orm import Database, db_session
import time
db = Database('mysql', host="localhost", port=3306, user="root",
passwd="123456", db="learn_pony")
class TryUpdate(db.Entity):
_table_ = "try_update_record"
t = Required(int, default=0)
db.generate_mapping(create_tables=True)
@db_session
def insert_record():
new_t = TryUpdate()
@db_session
def update():
t = TryUpdate.get(id=1)
print t.t
t.t = 0
print t.t
if __name__ == "__main__":
insert_record()
update()
Run Code Online (Sandbox Code Playgroud)
pony.orm报告异常:pony.orm.core.CommitException:对象TryUpdate [1]在当前事务之外更新.但是根本没有其他交易在运行
正如我的实验所示,只要tt更改为与原始值不同的值,pony就可以正常工作,但是当tt设置为等于原始值的值时,它总是会报告异常.
我不确定这是否是一个设计决定.在分配之前,我是否必须检查输入值是否每次都在变化?或者我有什么办法可以避免这个烦人的异常?
我的小马版:0.4.8
Thansk很多~~~
我有动态条件的查询,即
select (lambda obj:obj.A = 'a' and obj.B = 'b' and ...)
Run Code Online (Sandbox Code Playgroud)
所以我为此编写代码:
def search(self,**kwargs):
q = unicode('lambda obj:', 'utf-8')
for field,value in kwargs.iteritems():
value = unicode(value, 'utf-8')
field = unicode(field, 'utf-8')
q+=u" obj.%s == '%s' and" % (field,value
q = q[0:q.rfind('and')]
res = select(q.encode('utf-8'))[:]
Run Code Online (Sandbox Code Playgroud)
但我在执行函数时遇到此错误:
tasks.search(title='?????? 1',url='test.com')
res = select(q.encode('utf-8'))[:]
File "<string>", line 2, in select
File ".../local/lib/python2.7/site-packages/pony/utils.py", line 96, in cut_traceback
return func(*args, **kwargs)
File ".../local/lib/python2.7/site-packages/pony/orm/core.py", line 3844, in select
if not isinstance(tree, ast.GenExpr): throw(TypeError)
File "...local/lib/python2.7/site-packages/pony/utils.py", line …Run Code Online (Sandbox Code Playgroud) 这是我的实体:
class Article(db.Entity):
id = PrimaryKey(int, auto=True)
creation_time = Required(datetime)
last_modification_time = Optional(datetime, default=datetime.now)
title = Required(str)
contents = Required(str)
authors = Set('Author')
class Author(db.Entity):
id = PrimaryKey(int, auto=True)
first_name = Required(str)
last_name = Required(str)
articles = Set(Article)
Run Code Online (Sandbox Code Playgroud)
这是我用来获取一些数据的代码:
return left_join((article, author) for article in entities.Article
for author in article.authors).prefetch(entities.Author)[:]
Run Code Online (Sandbox Code Playgroud)
无论我是否使用 prefetch 方法,生成的 sql 看起来总是一样的:
SELECT DISTINCT "article"."id", "t-1"."author"
FROM "article" "article"
LEFT JOIN "article_author" "t-1"
ON "article"."id" = "t-1"."article"
Run Code Online (Sandbox Code Playgroud)
然后当我迭代结果时,小马正在发出另一个查询(查询):
SELECT "id", "creation_time", "last_modification_time", "title", "contents"
FROM "article"
WHERE …Run Code Online (Sandbox Code Playgroud) 我尝试用小马orm中的order_by聚合实现一个简单的选择:
因此,我尝试了以下方法:第一种方法引发错误消息:
sel = select((f.Name, f.id) for f in Firma).order_by(Firma.Name)
Run Code Online (Sandbox Code Playgroud)
这样,我从python中收到错误消息:“ NotImplementedError:按属性排序仅限于返回简单对象列表的查询。请尝试使用其他形式的排序(通过元组元素编号或成熟的lambda expr)”
第二种方式是选择顺序正常,但是在我的词典中插入会破坏已选择的选择顺序
for f in Firma.select(lambda f: f.Name) \
.order_by((Firma.Name)):
dic[f.Name] = f.id
print ("=== f.Name", f.Name)
dic[f.Name] = f.id
print(" === dic[f.Name]", dic[f.Name])
Run Code Online (Sandbox Code Playgroud)
结果如下:
=== f.Name A
=== dic[f.Name] 10
=== f.Name B
=== dic[f.Name] 11
=== f.Name C
=== dic[f.Name] 12
=== f.Name Neckermann
=== dic[f.Name] 7
=== f.Name Otto
=== dic[f.Name] 6
=== f.Name Quelle
=== dic[f.Name] 3
=== f.Name Testfirma
=== dic[f.Name] 9
=== …Run Code Online (Sandbox Code Playgroud) 我想知道是否应该尽量减少 db_session 的使用?让我们考虑这两个等效的例子:
A)
def do_stuff():
with db_session:
task = orm.make_proxy(Task.select().first())
task.mark_started()
...
this_function_might_take_a_long_time(task)
...
with db_session:
task.mark_done()
Run Code Online (Sandbox Code Playgroud)
二)
@db_session
def do_stuff():
task = Task.select().first()
task.mark_started()
commit()
...
this_function_might_take_a_long_time(task)
...
task.mark_done()
Run Code Online (Sandbox Code Playgroud)
通过阅读文档,我可以看出 Pony不鼓励对db_sessions 进行微观管理
With this code each of view function you will define will be wrapped with db_session so you should not care about them.
Run Code Online (Sandbox Code Playgroud)
然而,这里 表明打开它可能会产生成本(编辑:它没有,请阅读答案)
Before sending the first query, Pony gets a database connection from the connection pool.
Run Code Online (Sandbox Code Playgroud)
我是否正确地说,B 之外的任何内容都是过早优化,并且仅应在有限的数据库连接数场景中考虑 A?
python orm database-connection premature-optimization ponyorm
我已经开始使用Pony,但实际上还没有理解如何使用连接.在示例中,我看到当left_join()与两个for子句一起使用时,但是当我尝试在我的代码中重复它时,我得到的错误就像"收集预期,得到"p in Pond""也许有人可以解释如何使用它还是指向我已经解释过的文档页面?
我有一个app(Flask/Pony ORM)容器,必须在启动时注册postgres db容器的主机.我怎样才能获得主持人(postgres容器)的位置?
在我的本地设置中,我有"localhost"但这在app容器中不起作用.
我尝试了"172.17.0.2",这是我不使用docker-compose 时的pg容器IP .
但这两个都返回错误.
有没有办法在docker-compose文件中为特定容器指定主机位置?
我开始尝试使用对象关系映射器(特别是Pony ORM)。
在Pony中,所有实体定义都继承自类db.Entity。然而,为了做到这一点,当然db需要首先在某个地方创建对象。(db.Entity有点类似于sqlalchemy中的声明性基础,所以我相信下面的问题对于sqlalchemy也同样有效)
我在 Pony ORM 文档中看到的所有示例都提供了内联示例,其中数据库对象db只是在声明实体之前在解释器提示符中声明。
这给我留下了一个问题:我应该在“真实”项目中在哪里创建我的数据库对象?
特别考虑这样的情况:我希望将实体定义与实际使用这些实体的位置分开(假设我只想构建一个漂亮的 ORM 包装器包来访问数据库,然后应该在多个不同的其他项目中使用该数据库)。然后我可能希望用户提供db根据他们的需要配置的自己的对象,以便访问数据库。
假设我有一个存储人员和地址的数据库,我的包my_orm应该为该数据库提供一个 ORM,然后将其用于app.py:
my_orm/初始化.py
from my_orm.person import Person
from my_orm.address import Address
Run Code Online (Sandbox Code Playgroud)
my_orm/person.py:
from pony.orm import Required
class Person(db.Entity): # Where should `db` be defined?
name = Required(str)
age = Required(int)
Run Code Online (Sandbox Code Playgroud)
my_orm/address.py:
from pony.orm import Required
class Address(db.Entity): # Where should `db` …Run Code Online (Sandbox Code Playgroud) 我的程序有一个奇怪的问题,异常堆栈是:
*except Exception, cause: raise ExprEvalError(src, cause)
ExprEvalError: date_after raises NameError: name 'date_after' is not defined*
Run Code Online (Sandbox Code Playgroud)
所以代码是:
@staticmethod
def get_recently(days_before=30):
delta = timedelta(days=days_before)
date_after = datetime.now() - delta
return list(Version.select(lambda v:v.create_time>date_after).order_by(desc(Version.create_time))[:])
Run Code Online (Sandbox Code Playgroud)
ORM框架是Pony,但我认为它与此无关.代码可以在其他PC上正常运行.
你能告诉我这是什么问题吗?谢谢.
PS
ponyorm ×13
python ×9
orm ×6
postgresql ×2
attributes ×1
database ×1
docker ×1
flask ×1
many-to-many ×1
nameerror ×1
pony ×1
sql ×1
sql-order-by ×1
sqlalchemy ×1
transactions ×1