Anonymous
The test suite executes about 8,000 lines of tests in 80-100 seconds (depending on the hardware ~ i5 / i7)
Anonymous
That's pretty much it.
Anonymous
I can write a short tutorial if anyone is interested?
Alexander
It think it would be cool. Maybe a blogpost
Anonymous
ichux
ichux
Anonymous
I could set up (yet another) webservice that receives a ping from Process 1 and then looks at the jobqueue, but I'd like the seperation of "www" and "db background" which a trigger gives.
ichux
Matthew
Hi,
I got distracted a few weeks ago, now finishing off my testing of the "LIMIT 2" get composite key bug fix.
Matthew
With 0.7.3, I now get no LIMIT at all, where there used to be LIMIT 2
Matthew
In [4]: models.ReviewProduct.get(asin='12345678', country_code='UK')
SELECT "id", "asin", "country_code", "title", "image_url", "created", "first_review_scrape", "scheduled"
FROM "ReviewProduct"
WHERE "asin" = ?
AND "country_code" = ?
[u'12345678', u'UK']
Matthew
this is with composite_key(asin, country_code)
Matthew
is that the correct behaviour?
Matthew
This is with SQLite running locally
Alexander
Looks like a bug, I'll check it
Matthew
My apologies for not being able to test properly after your fix
Lucky
Alexander
Hi Lucky, some people are interested to know what is bonbot and how it works
Alexander
Cool!
Matthew
Can you link to the commit where the GET fixed was implemented please?
Matthew
https://github.com/ponyorm/pony/commit/fcecf7a28f5c0483334a54ff31c8b25553de8bdc nevermind, got it
Alexander
Sure, wait a second
Matthew
Always the way, I find stuff as soon as I ask
Alexander
Ok, good :)
Matthew
By the way, the reason this is important to me is that with a big products table, if a user adds 1000 products, and with 1000 GETs, the inefficient queries make it quite slow
Matthew
I know I could do one query but it would make the code harder to deal with
Matthew
Without composite key, on live database:
Matthew
app=> select * from reviewproduct where asin='12345678' and country_code='UK';
id | asin | country_code | title | image_url | created | first_review_scrape | scheduled
—--+------+--------------+-------+-----------+---------+---------------------+---------—
(0 rows)
Time: 3.070 ms
app=> select * from reviewproduct where asin='12345678' and country_code='UK' limit 1;
id | asin | country_code | title | image_url | created | first_review_scrape | scheduled
—--+------+--------------+-------+-----------+---------+---------------------+---------—
(0 rows)
Time: 0.550 ms
Matthew
oh, that's because of caching, but I do remember there being a significant difference
Alexander
I just tested queries with composite keys, they looks good:
from pony.orm import *
db = Database('sqlite', ':memory:')
class X(db.Entity):
a = Required(int)
b = Required(int)
c = Required(int)
composite_key(a, b)
db.generate_mapping(create_tables=True)
with db_session:
X(a=1, b=2, c=3)
X(a=4, b=5, c=6)
with db_session(sql_debug=True):
x1 = X.get(a=1, b=2)
x2 = X.get(b=5, c=6)
The result:
SELECT "id", "a", "b", "c"
FROM "X"
WHERE "a" = ?
AND "b" = ?
[1, 2]
SELECT "id", "a", "b", "c"
FROM "X"
WHERE "b" = ?
AND "c" = ?
LIMIT 2
[5, 6]
Matthew
Shouldn't x1 have LIMIT 1?
Alexander
It should be unnecessary, because database already know that combination of a and b is unique, so at most one row should be retrieved, and the database sould take that into account when generating a query plan
Alexander
Like, when you retrieve object by primary key, you don't add LIMIT 1 to the query
Alexey
Alexander
So, in your example:
select * from reviewproduct where asin='12345678' and country_code='UK';
if asin and country_code is an unique combination, you need to add UNIQUE index to the database using composite_key
Matthew
Yes, I think you're right
Matthew
this is the problem with leaving something for a few weeks, I forget details :)
Alexander
If for some reason it is not an unique combination in general, but you are pretty sure that for this specific values it is unique, you can write query as:
ReviewProduct.select() \
.filter(asin='12345678', country_code='UK).first()
This query will be with LIMIT 1 because of first(). But it will not be very efficient, because database will do sequential scan in order to find the row. So, adding UNIQUE index to the database is better
Matthew
Yeah, they will always be unique
Anonymous
Anonymous
I think the culprit is the decorator in pony.utils.utils.py
Anonymous
@decorator
def cut_traceback(func, *args, **kwargs):
if not (pony.MODE == 'INTERACTIVE' and options.CUT_TRACEBACK):
return func(*args, **kwargs)
.....
Matthew
How many inserts per transaction?
Anonymous
2000 per commit
Matthew
How long is it taking?
Anonymous
about 2 seconds per commit (to memory)
Anonymous
Matthew
Can you show the code?
Anonymous
Anonymous
...it's the lower loop.
Anonymous
for row in iterrows()...
Anonymous
Anonymous
Here's the schema:
Anonymous
Anonymous
Here's a call graph if it helps?
Lucky
Lucky
Lucky
Thus not adding overhead to every call
Lucky
Sorry for bad mobile typing
Def cut_trceback_decorator(func):
Def cut_traceback(*args,**kwargs):
Try: func(*args,**kwargs)
#etc.
# end def
If interactive: return func
Else: return cut_traceback
Alexander
I agree that we probably can remove decorator if pony mode is not interactive. But actually, its overhead is very small. If I understand correctly, 57.7% of time was spent not in decorator, but inside a wrapped functions, that is, commit and Entity.__init__. The time that was spent in decorator itself is 251ms (0.9%)
Lucky
Anonymous
Hi everyone. Sorry if it's not the place to ask but I can not find the answer to my problem on Google. I would like to know if it's possible to have a relation one to many between two entities using two keys (both are the primary key). I've tried to use the model created by online editor and It's not working. :
Anonymous
class Faclin2(db.Entity):
facl_facc_id = Required(int)
facl_facc_serie = Required(str)
facl_descripcion = Optional(str)
PrimaryKey(facl_facc_id, facl_facc_serie)
class Faccab2(db.Entity):
facc_id = Required(int)
facc_serie = Required(str)
facc_fecha = Optional(date)
facc_cli_id = Required(int)
faclin2s = Set(Faclin2) # the problem
PrimaryKey(facc_id, facc_serie)
Matthew
What is the error you get?
Anonymous
pony.orm.core.ERDiagramError: Reverse attribute for Faccab2.faclin2s not found
Anonymous
Thank you in advance!
Alexander
In Pony it is necessary to define both sides of relationship. If it is one-to-many, that means that each Faclin2 may have at most one Faccab2. So you need to add Required or Optional attribute to Faclin2:
class Faclin2(db.Entity):
...
faccab2 = Required("Faccab2")
or
class Faclin2(db.Entity):
...
faccab2 = Optional("Faccab2")
Matthew
I was about to say this but saw that Alexander was typing, and he's the expert :)
Anonymous
Thank you very much Alenxander and Matthew but I continue getting the same error
Anonymous
I made a mistake in my model. this is the right model from de online editor: class Faccab2(db.Entity):
facc_id = Required(int)
facc_serie = Required(str)
facc_cli_id = Required(int)
facc_fecha = Optional(date)
faclin2s = Set('Faclin2')
PrimaryKey(facc_id, facc_serie)
class Faclin2(db.Entity):
facl_facc_id = Required(int)
facl_facc_serie = Required(str)
facl_facc_descripcion = Optional(str)
faccab2 = Required(Faccab2)
PrimaryKey(facl_facc_id, facl_facc_serie)
Alexander
The code that you posted is working without any error
Anonymous
I get the error: pony.orm.core.ERDiagramError: Reverse attribute for Clientes2.faccab2s not found
Anonymous
Sorry
Anonymous
This one: pony.orm.dbapiprovider.OperationalError: (1054, "Unknown column 'faclin2.facl_facc_descripcion' in 'field list'")
Alexander
If the database at this moment is not containing important data, you can drop prevous tables and create a new tables with additional columns
Anonymous
Thank you very much Alexander for your time
Alexander
Sure