views:

18

answers:

1

I'm using the MySQLicious type schema described here for a simple tagging system. I've read some alternative implementations of tagging schema in 4 different SO threads, and this suits my needs best.

A collection of entries have the tags "apple banana orange" and "strawberry banana lemon", and I'm trying to find the Elixir/SQLAlchemy equivalent statement to

SELECT * FROM table WHERE tags LIKE "%banana%";

I haven't been able to find any such way to structure a Class.query.filter/filter_by() command, and can't see a similar method in the documentation for either module. Is there a simple way to do this? Or should I just use raw SQL.

Extra Question: A disadvantage of the MySQLicious schema is the case where I may wish to search for "%apple%" but have "pineapple" returned. Is there a high level way to deal with this test case? Or should I just include a leading space in each query?

n.B: For those who care, this is my first experience with databases, so I may be overlooking core advantages of the schema mentioned in other threads. My application is for logging a sentence or two about a task completed, with columns [TaskID, Tags, Notes, StartTime, StopTime, TimeTaken], a bit like a simple journal. Mostly for tutorial purposes. I want to be able to search by individual tags to find out roughly how much time I spend on a given task.

+1  A: 

Each column has .like method, which can be used as filter clause.

>>> Note.query.filter(Note.message.like("%somestr%")).all()
[]
Daniel Kluev
Perfect!Do you know if there's a better way to distinguish between apple and pineapple than adding a leading space?
Gary Oldfaber
Best way would be to just normalize your database and add 2 separate tables for tags and tag-to-task relations, and then use JOINs instead of LIKE. Otherwise, yes, seems like you will have to have some kind of separator around each tag in the string. Leading space is not enough, since there is also pen and pencil, with %pen%. If you do something like "|apple|pineapple|pen|pencil|" and match "%|pen|%" it should not collide.
Daniel Kluev
With normalizing, I'm not quite sure how I'll have more than one tag associated with a given task, or vice versa using the tag map. The "Toxi" solution appears to group the collection of tags as a single item, rather than storing each individually? And the method used in this (http://elixir.ematia.de/trac/wiki/Recipes/TagCloud) recipe appears to only allow one tag per item.What resources would be best for elucidating this topic? I've read this (http://dev.mysql.com/tech-resources/articles/intro-to-normalization.html) too, but can't picture how to manage multiple tags.
Gary Oldfaber
As I said, you need two tables. Basically, its just typical Many-to-Many relation, so you can follow SQLAlchemy's guide on it: http://www.sqlalchemy.org/docs/ormtutorial.html#building-a-many-to-many-relationship You will have `tags` table, where you store tag name and other tag info, and you will have `task_tags` table, which will have one record for each tag added to the task. So task with 2 tags will just have 2 records in `task_tags` table.
Daniel Kluev
Thanks, I really appreciate the help.
Gary Oldfaber