Skip to content

Instantly share code, notes, and snippets.

@josiahcarlson
Last active August 8, 2019 04:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save josiahcarlson/dfb3c5335b103e29caedbc6c18199fd1 to your computer and use it in GitHub Desktop.
Save josiahcarlson/dfb3c5335b103e29caedbc6c18199fd1 to your computer and use it in GitHub Desktop.
Example from a livecoding stream, updated with fixes
'''
This this was retyped from https://www.twitch.tv/videos/459202303 for notes and
then updated by the author of rom, me, Josiah Carlson
Notes:
* For created_at, or any default, if it is "callable", it will be called at
entity creation/instantiation. In the demo in the video, we see:
created_at = rom.DateTime(default=datetime.datetime.now())
This should have been:
created_at = rom.DateTime(default=datetime.datetime.now)
... Because otherwise, the now() is called on import, not on User() creation.
Though arguably, it should have been
created_at = rom.DateTime(default=datetime.datetime.utcnow)
... so we don't have to worry about timezones.
* The FULL_TEXT index keygen mangles tokens on their way through to the
indexing step:
In [2]: rom.FULL_TEXT('My Task #1')
Out[2]: ['1', 'my', 'task']
Those tokens are then indexed and searchable according to the `prefix` /
`suffix` / `pattern` options provided.
If you provided `prefix=True`, you can use:
`Model.query.startswith(attr=...)`
`Model.query.like(attr=...)`
If you provided `suffix=True`, you can use:
`Model.query.endswith(attr=...)`
So in the example video with `description="My Task #{}"`, these all return
results:
Task.query.startswith(description='4')
Task.query.like(description='*as')
Task.query.endswith(description='sk')
Task.query.startswith(description='Task')
Task.query.startswith(description='M')
These won't:
# the '#' token is stripped in FULL_TEXT index, so won't find anything if
# passed during query; you can use your own custom keygen to decide what
# you want to search for
Task.query.startswith(description='#4')
Other queries that failed during the session may have failed because the data
wasn't indexed / reindexed properly. See:
https://josiahcarlson.github.io/rom/util.html#rom.util.refresh_indices
https://josiahcarlson.github.io/rom/util.html#rom.util.show_progress
* For usernames, email addresses, and similar, where you don't want to mangle
the data you want to query for (except for case-sensitivity maybe), the
`rom.IDENTITY` and `rom.IDENTITY_CI` are probably what you're looking for:
In [3]: rom.IDENTITY('MyUsername1')
Out[3]: ['MyUsername1']
In [4]: rom.IDENTITY_CI('MyUsername1')
Out[4]: ['myusername1']
----
The below should serve as an updated example that addresses some of the
questions brought up in the video.
Thank you for recording the video Bruno! Thank you everyone else for watching
and reading!
'''
import rom
import datetime
rom.util.set_connection_settings(db=9)
class User(rom.Model):
id = rom.PrimaryKey()
username = rom.String(required=True, unique=True, keygen=rom.IDENTITY_CI, index=True)
unsave_password = rom.String(required=True)
tasks = rom.OneToMany('Task')
created_at = rom.DateTime(default=datetime.datetime.now)
class Task(rom.Model):
id = rom.PrimaryKey()
description = rom.String(default=b'', index=True, keygen=rom.FULL_TEXT, prefix=True, suffix=True)
is_done = rom.Boolean(default=False, index=True)
user = rom.ManyToOne('User', on_delete='cascade')
# get_by() works on most simple indexes, and here we exploit the unique index
user = User.get_by(username=b'Bruno')
if not user:
user = User(username=b'Bruno', unsave_password=b'bad_password')
user.save()
for i in range(10):
task = Task(description="My Task #{}".format(i), user=user)
task.save()
rom.session.commit()
# these should all produce results
for task in Task.query.startswith(description='4'):
print("got task startswith number:", task.description)
for task in Task.query.endswith(description='4'):
print("got task endswith number:", task.description)
for task in Task.query.like(description='*as'):
print("got task like:", task.description)
for task in Task.query.endswith(description='sk'):
print("got task endswith:", task.description)
for task in Task.query.startswith(description='Task'):
print("got task startswith uppercased 1:", task.description)
for task in Task.query.startswith(description='M'):
print("got task startswith uppercased 2:", task.description)
for user in User.query.all():
user.delete()
for task in Task.query.all():
task.delete()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment