Storm model query created invalid sql
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Storm |
Incomplete
|
Undecided
|
Unassigned |
Bug Description
With the following model query
store = storm_store.
from storm.tracer import debug
debug(True)
billing_address = storm_store.
Causes the following sql to be used to query the database. As you can see the where clause is invalid.
SELECT customer_
FROM customer_address
WHERE customer_
If I dont have the one() function call at the end, the query is accurate
Below is my model
"""
Module that contains the model that represents the 1...nth address of a customer
"""
from storm.locals import Unicode, Int, Reference, DateTime, Storm
import pytz
from api.models.common import AuditedModel
#pylint:
def validate_
"""
Validate that a value passed into the state is a valid state.
"""
state_list = [u'ACT', u'NSW', u'VIC', u'QLD', u'WA', u'SA', u'TAS', u'NT']
if value not in state_list:
raise ValueError(
else:
return value
def validate_
"""
Validate that the address type is one of address_types
"""
address_type = [u'Physical', u'Billing', u'Shipping', u'Mailing']
if value not in address_type:
raise ValueError(
else:
return value
def validate_
"""
Validate the timezone string
"""
if value not in pytz.country_
raise ValueError("The timezone '%s' passed does not exist in pytx.country_
else:
return value
class Address(
"""
An instance of an address for a store
"""
__storm_table__ = 'customer_address'
id = Int(primary=True)
phone = Unicode()
fax = Unicode()
address = Unicode()
city = Unicode()
state = Unicode(
postcode = Unicode()
country = Unicode()
store_id = Int()
timezone = Unicode(
date_deleted = DateTime()
store = Reference(
address_type_id = Int()
address_type = Reference(
class AddressType(Storm):
"""
Lookup table for address type
"""
__storm_table__ = 'customer_
id = Int(primary=True)
type = Unicode(
the following is the create table in postgres
CREATE TABLE customer_address
(
id bigint NOT NULL DEFAULT nextval(
phone text NOT NULL,
fax text,
address text NOT NULL,
city text NOT NULL,
state text NOT NULL,
postcode text NOT NULL,
country text NOT NULL,
created_audit_id numeric(20,0),
deleted_audit_id numeric(20,0),
last_
date_deleted timestamp without time zone,
store_id bigint NOT NULL,
timezone text NOT NULL,
address_type_id bigint NOT NULL,
CONSTRAINT pk_customer_address PRIMARY KEY (id),
CONSTRAINT fk_customer_
REFERENCES common_audit_data (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT fk_customer_
REFERENCES common_audit_data (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT fk_customer_
REFERENCES common_audit_data (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT fk_customer_
REFERENCES customer_
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT fk_customer_
REFERENCES customer_store (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT uq_store_
)
System:
Python 2.6.5
storm 0.19
psycopg2 2.4.2
postgres 9.0
ubuntu 10.04
I have the workaround, ie using it without the one() call but thought I should file a bug anyway.
description: | updated |
The code fragment you've listed in the description looks a bit weird to me:
store = store.find( models. customer. Store, models. customer. Store.id == contract. store_id) .one()
When this is executed, presumably "store" is a storm.store.Store instance. After it executes, it will be a models. customer. Store instance. While there is nothing stopping you doing this kind of thing in Python, it does make it more difficult to debug or understand the code.
So in the next query, you're executing the models. customer. Store.find( ) method instead of storm.store. Store.find( ). You haven't included any information about that class in your code snippet, so it is difficult to tell what it might be doing.
Looking at the resulting SQL though, it appears that the first argument is being treated as part of the where clause (hence the table name appearing bare). Storm does have a few find() methods that act similar to this by not taking the first argument of Store.find() such as ResultSet.find() and BoundReferenceS et.find( ) (both of which use the same class list as the container they act on). Perhaps you used one of those?