請問query可以搜索Reference的表中的各個欄位中的值嗎?

6 views
Skip to first unread message

SeedSeek

unread,
Nov 13, 2011, 10:37:29 AM11/13/11
to Uliweb
假設我有兩個表
class A:
a1 = Field(str, max_length=20, required=True)
a2 = Field(str, max_length=128)

def __unicode__(self):
return u'%s_%s' % (self.a1, self.a2)

class B:
b1 = Reference('a')

在B表的list中用query 可以搜索A的__unicode__輸出的值嗎?
或者
在B表的list中用query 可以搜索A表所有欄位的值嗎?

應該要注意哪些細節

感謝

limodou

unread,
Nov 13, 2011, 7:58:04 PM11/13/11
to uli...@googlegroups.com
2011/11/13 SeedSeek <frt5...@gmail.com>:

目前ORM的一个Model主要是用来搜索这个Model下的数据,然后在遍历每条数据时,再去通过关系来获得对主应的数据。此时会引发另一条sql语句来获取。因此,如果你要同时获得A,B表的字段,需要使用sqlalchemy的select([fields],
where)来获得记录。

以后可以考虑以一种方便的形式来同时获取主表和关联表的记录,减少sql语句,但是通过増加连接处理。

--
I like python!
UliPad <<The Python Editor>>: http://code.google.com/p/ulipad/
UliWeb <<simple web framework>>: http://code.google.com/p/uliweb/
My Blog: http://hi.baidu.com/limodou

SeedSeek

unread,
Nov 27, 2011, 8:18:12 PM11/27/11
to Uliweb
select([fields], where)
在Uliweb 要怎麼要怎麼寫?

感謝
On Nov 14, 8:58 am, limodou <limo...@gmail.com> wrote:
> 2011/11/13 SeedSeek <frt524...@gmail.com>:

limodou

unread,
Nov 27, 2011, 8:23:22 PM11/27/11
to uli...@googlegroups.com
2011/11/28 SeedSeek <frt5...@gmail.com>:

> select([fields], where)
> 在Uliweb 要怎麼要怎麼寫?
>

你可以直接使用上面的语句,对于uliorm来说,可以使用Model.c.field和sqlalchemy的table.c.field是一样的。另外Model.table就是sqlalchemy的table对象,比如上面,可以写为:

select([User.table])

这个是全部字段,也可以指定字段,如:

select([User.c.username, User.c.email])

不过,如果只是一个表的话,就没必要使用select了,可以使用:

User.all()或User.all().values(User.c.username, User.c.email),更ORM的用法。

SeedSeek

unread,
Jan 6, 2012, 7:39:10 AM1/6/12
to Uliweb
from sqlalchemy.sql import select
select([User.c.username, User.c.email]).like('%'+c['username']+'%')
select([User.c.username.like('%'+c['username']+'%'),
User.c.email.like('%'+c['username']+'%')])

以上兩個都沒辦法操作
請問這樣是不是寫錯了?


On Nov 28 2011, 9:23 am, limodou <limo...@gmail.com> wrote:
> 2011/11/28 SeedSeek <frt524...@gmail.com>:


>
> > select([fields], where)
> > 在Uliweb 要怎麼要怎麼寫?
>

> 你可以直接使用上面的语句,对于uliorm来说,可以使用Model.c.field和sqlalchemy的table.c.field是一样的。另外Mo del.table就是sqlalchemy的table对象,比如上面,可以写为:

limodou

unread,
Jan 6, 2012, 8:41:29 AM1/6/12
to uli...@googlegroups.com
2012/1/6 SeedSeek <frt5...@gmail.com>:

> from sqlalchemy.sql import select
> select([User.c.username, User.c.email]).like('%'+c['username']+'%')

select([User.c.username, User.c.email],
User.c.username.like('%'+c['username']+'%‘)

> select([User.c.username.like('%'+c['username']+'%'),
> User.c.email.like('%'+c['username']+'%')])
>

字段列表和条件在select中是两个参数。

SeedSeek

unread,
Jan 6, 2012, 9:00:28 AM1/6/12
to Uliweb
這樣寫一樣可以達到多個欄位查詢同一個值嗎?

On Jan 6, 9:41 pm, limodou <limo...@gmail.com> wrote:
> 2012/1/6 SeedSeek <frt524...@gmail.com>:

limodou

unread,
Jan 6, 2012, 9:04:43 AM1/6/12
to uli...@googlegroups.com
2012/1/6 SeedSeek <frt5...@gmail.com>:

> 這樣寫一樣可以達到多個欄位查詢同一個值嗎?
>
> On Jan 6, 9:41 pm, limodou <limo...@gmail.com> wrote:
>> 2012/1/6 SeedSeek <frt524...@gmail.com>:
>>
>> > from sqlalchemy.sql import select
>> > select([User.c.username, User.c.email]).like('%'+c['username']+'%')
>>
>> select([User.c.username, User.c.email],
>> User.c.username.like('%'+c['username']+'%')
>>
>> > select([User.c.username.like('%'+c['username']+'%'),
>> > User.c.email.like('%'+c['username']+'%')])
>>
>> 字段列表和条件在select中是两个参数。
>>

什么意思?

SeedSeek

unread,
Jan 6, 2012, 9:19:02 AM1/6/12
to Uliweb
應該算是關鍵字搜尋
在欄位清單中的欄位內的值
只要有類似條件的值
這一筆就等於符合搜尋條件

範例字典檔
{username:'abc', email:'1...@gmail.com'}
{username:'cde', email:'4...@gmail.com'}
{username:'efg', email:'b...@gmail.com'}

當我查詢 'b' 的時候,只要username 或email 欄位中的值有 'b' 條件就成立
所以會查到
{username:'abc', email:'1...@gmail.com'}
{username:'efg', email:'b...@gmail.com'}

應該就這樣

SeedSeek

unread,
Jan 6, 2012, 9:22:31 AM1/6/12
to Uliweb
重寫一下,google 屏蔽了一些字

範例字典檔
{username:'abc', email:'1gmailcom'}
{username:'cde', email:'2gmailcom'}
{username:'efg', email:'bgmailcom'}


當我查詢 'b' 的時候,只要username 或email 欄位中的值有 'b' 條件就成立
所以會查到

{username:'abc', email:'...@gmail.com'}
{username:'efg', email:'...@gmail.com'}

查詢 'a'
符合
{username:'abc', email:'1gmailcom'}
{username:'cde', email:'2gmailcom'}
{username:'efg', email:'bgmailcom'}

查詢 '1'
符合
{username:'abc', email:'1gmailcom'}

On Jan 6, 10:19 pm, SeedSeek <frt524...@gmail.com> wrote:
> 應該算是關鍵字搜尋
> 在欄位清單中的欄位內的值
> 只要有類似條件的值
> 這一筆就等於符合搜尋條件
>
> 範例字典檔

> {username:'abc', email:'...@gmail.com'}
> {username:'cde', email:'...@gmail.com'}
> {username:'efg', email:'...@gmail.com'}


>
> 當我查詢 'b' 的時候,只要username 或email 欄位中的值有 'b' 條件就成立
> 所以會查到

> {username:'abc', email:'...@gmail.com'}
> {username:'efg', email:'...@gmail.com'}

limodou

unread,
Jan 6, 2012, 9:35:39 AM1/6/12
to uli...@googlegroups.com
2012/1/6 SeedSeek <frt5...@gmail.com>:

> 重寫一下,google 屏蔽了一些字
>
> 範例字典檔
> {username:'abc', email:'1gmailcom'}
> {username:'cde', email:'2gmailcom'}
> {username:'efg', email:'bgmailcom'}
> 當我查詢 'b' 的時候,只要username 或email 欄位中的值有 'b' 條件就成立
> 所以會查到
> {username:'abc', email:'...@gmail.com'}
> {username:'efg', email:'...@gmail.com'}
>
> 查詢 'a'
> 符合
> {username:'abc', email:'1gmailcom'}
> {username:'cde', email:'2gmailcom'}
> {username:'efg', email:'bgmailcom'}
>
> 查詢 '1'
> 符合
> {username:'abc', email:'1gmailcom'}
>

那这是一个或者的关系,可以这样

select([User.c.username, User.c.email],
User.c.username.like('%'+c['username']+'%') |
User.c.email.like('%'+c['username']+'%'))

limodou

unread,
Jan 6, 2012, 9:36:03 AM1/6/12
to uli...@googlegroups.com
2012/1/6 limodou <lim...@gmail.com>:

> 2012/1/6 SeedSeek <frt5...@gmail.com>:
>> 重寫一下,google 屏蔽了一些字
>>
>> 範例字典檔
>> {username:'abc', email:'1gmailcom'}
>> {username:'cde', email:'2gmailcom'}
>> {username:'efg', email:'bgmailcom'}
>> 當我查詢 'b' 的時候,只要username 或email 欄位中的值有 'b' 條件就成立
>> 所以會查到
>> {username:'abc', email:'...@gmail.com'}
>> {username:'efg', email:'...@gmail.com'}
>>
>> 查詢 'a'
>> 符合
>> {username:'abc', email:'1gmailcom'}
>> {username:'cde', email:'2gmailcom'}
>> {username:'efg', email:'bgmailcom'}
>>
>> 查詢 '1'
>> 符合
>> {username:'abc', email:'1gmailcom'}
>>
>
> 那这是一个或者的关系,可以这样
>
> select([User.c.username, User.c.email],
> User.c.username.like('%'+c['username']+'%') |
> User.c.email.like('%'+c['username']+'%'))
>

还可以使用or_来处理或者的关系。

SeedSeek

unread,
Jan 7, 2012, 4:51:25 AM1/7/12
to Uliweb
views.py

condition = None
condition = (select([User.c.username,
User.c.email], User.c.username.like('%'+c['username']+'%') |
User.c.email.like('%'+c['username']+'%'))) & condition
這樣的寫法會報錯,沒用select 的話就沒問題
這樣要如何解決?

On Jan 6, 10:36 pm, limodou <limo...@gmail.com> wrote:
> 2012/1/6 limodou <limo...@gmail.com>:
>
>
>
>
>
>
>
>
>
> > 2012/1/6 SeedSeek <frt524...@gmail.com>:

limodou

unread,
Jan 7, 2012, 7:25:47 AM1/7/12
to uli...@googlegroups.com
2012/1/7 SeedSeek <frt5...@gmail.com>:

> views.py
>
> condition = None
> condition = (select([User.c.username,
> User.c.email], User.c.username.like('%'+c['username']+'%') |
> User.c.email.like('%'+c['username']+'%'))) & condition
> 這樣的寫法會報錯,沒用select 的話就沒問題
> 這樣要如何解決?
>

condition相当于where条件的,不能有select啊。所以上面应该是:

condition = None
condition = (User.c.username.like('%'+c['username']+'%') |
User.c.email.like('%'+c['username']+'%')) & condition

SeedSeek

unread,
Jan 8, 2012, 3:04:13 AM1/8/12
to Uliweb
請問數字欄位也可以用 .like 嗎?
condition 好像試不出來

On Jan 7, 8:25 pm, limodou <limo...@gmail.com> wrote:
> 2012/1/7 SeedSeek <frt524...@gmail.com>:

limodou

unread,
Jan 8, 2012, 6:14:46 AM1/8/12
to uli...@googlegroups.com
2012/1/8 SeedSeek <frt5...@gmail.com>:

> 請問數字欄位也可以用 .like 嗎?
> condition 好像試不出來

数字只有比较大小吧。字符串才有like。这是数据库的查询要求。

SeedSeek

unread,
Jan 11, 2012, 6:23:50 AM1/11/12
to Uliweb
請問有多層Reference 關係的表可以反向查詢幾層?

On Jan 8, 7:14 pm, limodou <limo...@gmail.com> wrote:
> 2012/1/8 SeedSeek <frt524...@gmail.com>:

limodou

unread,
Jan 11, 2012, 7:23:57 AM1/11/12
to uli...@googlegroups.com
2012/1/11 SeedSeek <frt5...@gmail.com>:
> 請問有多層Reference 關係的表可以反向查詢幾層?
>

不太明白。

SeedSeek

unread,
Jan 11, 2012, 8:05:43 AM1/11/12
to Uliweb
Class A(Model):
Workpiece = Field(str)

Class B(Model):
Workpiece = Reference('a')
Parts = Field(str)

Class C(Model):
Parts = Reference('b')
Package = Field(str)

Class D(Model):
Package = Reference('c')
EndProduct = Field(str)

上面有四層關聯
如果要從Class D 往上反查
需要甚麼條件?


On 1月11日, 下午8時23分, limodou <limo...@gmail.com> wrote:
> 2012/1/11 SeedSeek <frt524...@gmail.com>:

limodou

unread,
Jan 11, 2012, 9:25:01 AM1/11/12
to uli...@googlegroups.com
2012/1/11 SeedSeek <frt5...@gmail.com>:

> Class A(Model):
> Workpiece = Field(str)
>
> Class B(Model):
> Workpiece = Reference('a')
> Parts = Field(str)
>
> Class C(Model):
> Parts = Reference('b')
> Package = Field(str)
>
> Class D(Model):
> Package = Reference('c')
> EndProduct = Field(str)
>
> 上面有四層關聯
> 如果要從Class D 往上反查
> 需要甚麼條件?
>

如果要从D查到A还是比较简单,因为都是多对一的关系,所以假如D的对象是d,可以这样:

d.c.b.a

这样得到a

SeedSeek

unread,
Jan 11, 2012, 7:40:52 PM1/11/12
to Uliweb
如果在condition 和filter 也是這樣的用法嗎?

condition = (d.c.Package.Parts.Workpiece.Workpiece) == Workpiece) &
condition
d.filter(d.c.Package.Parts.Workpiece.Workpiece) == Workpiece)
這樣用法正確嗎?


On Jan 11, 10:25 pm, limodou <limo...@gmail.com> wrote:
> 2012/1/11 SeedSeek <frt524...@gmail.com>:
>
>
>
>
>
>
>
>
>

limodou

unread,
Jan 11, 2012, 9:21:38 PM1/11/12
to uli...@googlegroups.com
2012/1/12 SeedSeek <frt5...@gmail.com>:

> 如果在condition 和filter 也是這樣的用法嗎?
>
> condition = (d.c.Package.Parts.Workpiece.Workpiece) == Workpiece) &
> condition
> d.filter(d.c.Package.Parts.Workpiece.Workpiece) == Workpiece)
> 這樣用法正確嗎?
>

你要区分:实例.reference_field和Model.c.refernce_field是不同的概念。前者会引发一个查询,它是通过对象来查找对应的记录。而后者是一个字段,用来生成条件的。Reference是通过对象来关联的,不能直接通过field来关联,所以d.c.Package.Parts.Workpiece.Workpiece这样的用法是不对的。你要写成关联的形式,如:

(D.c.Package == C.c.id) & (C.c.Parts == B.c.id) & ...

所以你的写法condition和filter都是不对的。你可以print condition看一看生成的是什么东西就清楚了。

Reply all
Reply to author
Forward
0 new messages