コード例 #1
0
async def test_orm(app1):
    from app1.models.post import Post

    # Single where like
    query = Post.query().where('body', 'like', '%favorite%')
    assert query.sql() == {'main': 'SELECT DISTINCT posts.id, posts.unique_slug, posts.title, posts.body, posts.other, posts.creator_id, posts.owner_id FROM posts WHERE posts.body LIKE :body_1'}
    posts = await query.get()
    assert [2, 4] == [x.id for x in posts]

    # Multiple where like AND
    posts = await Post.query().where('body', 'like', '%favorite%').where('body', 'like', '%frameworks%').get()
    assert [2] == [x.id for x in posts]

    # Multiple where like AND using a LIST
    posts = await Post.query().where([
        ('body', 'like', '%favorite%'),
        ('body', 'like', '%frameworks%')
    ]).get()
    assert [2] == [x.id for x in posts]

    # Where like OR
    posts = await Post.query().or_where([
        ('body', 'like', '%favorite%'),
        ('body', 'like', '%love%'),
    ]).get()
    assert [2, 4, 5] == [x.id for x in posts]

    # Where like AND with where OR
    posts = await Post.query().where('body', 'like', '%like%').or_where([
        ('slug', 'test-post3'),
        ('slug', '=', 'test-post6'),
        ('slug', '=', 'test-post7'),
    ]).get()
    assert [3, 7] == [x.id for x in posts]
コード例 #2
0
async def test_where_attribute_dict(app1):
    # Filter posts based on a post attribute
    # This is using the experimental dict_where feature
    from app1.models.post import Post
    posts = await (Post.query().include('attributes').where('attributes.post1-test1', 'value for post1-test1').get())
    assert len(posts) == 1
    assert posts[0].id == 1
コード例 #3
0
async def test_single(app1):
    # Single NOT where like
    from app1.models.post import Post
    query = Post.query().where('body', '!like', '%favorite%')
    # Probably not as this could be dialect specific
    #assert query.sql() == {'main': 'SELECT DISTINCT posts.id, posts.unique_slug, posts.title, posts.body, posts.other, posts.creator_id, posts.owner_id FROM posts WHERE posts.body NOT LIKE :body_1'}
    posts = await query.get()
    assert [1, 3, 5, 6, 7] == [x.id for x in posts]
コード例 #4
0
async def test_where_attribute(app1):
    # Filter posts based on a post attribute
    # Using actual standard where key and value
    from app1.models.post import Post
    posts = await (Post.query()
        .include('attributes')
        .where([
            ('attributes.key', '=', 'badge'),
            ('attributes.value', 'IT'),
        ])
        .get()
    )
    assert len(posts[0].attributes) == 3
    assert len(posts[1].attributes) == 3
    assert len(posts[2].attributes) == 4
    assert [1, 2, 6] == [x.id for x in posts]
コード例 #5
0
async def XXXXXXXXXXXXXXXXXXXXXtest_get(app1):
    # The only example of a Polymorphic Many-To-Many is the hashtag table

    # FIXME, never done

    from app1.models.post import Post

    query = Post.query().include('attributes')

    sql = query.sql()
    dump(sql)

    posts = await query.get()

    dump(posts)

    assert False
コード例 #6
0
async def test_get(app1):
    # Get all
    from app1.models.post import Post
    query = Post.query().include('attributes')
    # Probably not as this could be dialect specific
    # assert query.sql() == {
    #     'main': 'SELECT DISTINCT posts.id, posts.unique_slug, posts.title, posts.body, posts.other, posts.creator_id, posts.owner_id FROM posts LEFT OUTER JOIN attributes ON attributes.attributable_type = :attributable_type_1 AND posts.id = attributes.attributable_id',
    #     'attributes': 'SELECT DISTINCT attributes.id AS "attributes__id", attributes.attributable_type AS "attributes__attributable_type", attributes.attributable_id AS "attributes__attributable_id", attributes.key AS "attributes__key", attributes.value AS "attributes__value" FROM posts LEFT OUTER JOIN attributes ON attributes.attributable_type = :attributable_type_1 AND posts.id = attributes.attributable_id WHERE attributes.id IS NOT NULL'
    # }
    posts = await query.get()
    pa = {x.id:x.attributes for x in posts}
    assert pa[1]['post1-test1'] == 'value for post1-test1' and len(pa[1]) == 3
    assert pa[1]['post1-test1'] == 'value for post1-test1' and len(pa[3]) == 1
    assert pa[2]['post2-test1'] == 'value for post2-test1' and len(pa[2]) == 3
    assert pa[6]['post6-test1'] == 'value for post6-test1' and len(pa[6]) == 4
    assert pa[4] == pa[5] == pa[7] == {}

    # Access attributes as a dict
    assert posts[0].attributes['badge'] == 'IT'
コード例 #7
0
ファイル: posts.py プロジェクト: uvicore/framework
async def seed():
    log.item('Seeding table posts')

    # Get all tags keyed by name
    tags = await Tag.query().key_by('name').get()

    # Get all hastags keyed by name
    hashtags = await Hashtag.query().key_by('name').get()

    #post = PostModel(slug='test-post1', title='Test Post1', other='other stuff1', creator_id=1)
    #await post.save()

    # Now I want to do inline, though has to be DIct
    # where I create the post with comments=[{dict}]

    # WORKS!!!
    await Post.insert_with_relations([
        {
            'slug':
            'test-post1',
            'title':
            'Test Post1',
            'body':
            'This is the body for test post1.  I like the color red and green.',
            'other':
            'other stuff1',
            'creator_id':
            1,
            'owner_id':
            2,
            'comments': [{
                'title': 'Post1 Comment1',
                'body': 'Body for post1 comment1',
                #'post_id': 1,  # No id needed, thats what post.create() does
                'creator_id': 1,
            }],

            # Many-To-Many tags works with existing Model, new Model or new Dict
            'tags': [
                # Existing Tag
                tags['linux'],
                tags['mac'],
                tags['bsd'],
                tags[
                    'bsd'],  # Yes its a duplicate, testing that it doesn't fail

                # New Tag as Model (tag created and linked)
                Tag(name='test1', creator_id=4),

                # New Tag as Dict (tag created and linked)
                {
                    'name': 'test2',
                    'creator_id': 4
                },
            ],

            # Polymorphic One-To-One
            'image': {
                'filename': 'post1-image.png',
                'size': 1234932,
            },

            # Polymorphic One-To-Many Attributes
            'attributes': [
                {
                    'key': 'post1-test1',
                    'value': 'value for post1-test1'
                },
                {
                    'key': 'post1-test2',
                    'value': 'value for post1-test2'
                },
                {
                    'key': 'badge',
                    'value': 'IT'
                },
            ],

            # Polymorphic Many-To-Many Hashtags
            'hashtags': [
                hashtags['important'],
                hashtags['outdated'],
                hashtags[
                    'outdated'],  # Yes its a duplicate, testing that it doesn't fail

                # New hashtag by model
                Hashtag(name='test1'),

                # New hashtag by dict
                {
                    'name': 'test2'
                },
            ],
        },
    ])

    # Example of adding attributes later
    post = await Post.query().find(1)

    # ISSUE:  How can we update an attribute that is a dict?
    # If it weren't a dict we could get it (post.attributes['badge']) then change an attribute then call post.attributes['badge'].save() probably
    # But if a dict, how can we update a value?  Doing a .create/.add like so
    # await post.add('attributes', [
    #     {'key': 'post1-test2', 'value': 'xxxx'},
    # ])
    # Gives us an Integrity error due to models.py insert() around line 92.  It assume a bulk insert and cannot upsert
    # If we don't pass a list it does a single insert which will also fail with IntegrityError.  I would have to add code
    # to know how to SELECT to see if exists based on PK or in the case of polymorphism, all 3 or more poly columns.

    # Example of adding attributes whos value is also a Dict - DOES NOT WORK YET, need auto-serialization, though I could serialize manually to str
    # await post.add('attributes', [
    #     {'key': 'post1-test3', 'value': {
    #         'this': 'value',
    #         'is': 'a dict itself!'
    #     }},
    #     {'key': 'post1-test4', 'value': ['one', 'two', 'three']}
    # ])

    # # Blow out all attributes and set this complete List
    # await post.set('attributes', [
    #     {'key': 'post1-test3', 'value': 'value for post1-test3'},
    #     {'key': 'post1-test4', 'value': 'value for post1-test4'},
    # ])

    # Example of setting all a Polymorphic Many-To-Many Hashtags - WORKS
    # await post.set('hashtags', [
    #     {'name': 'test1'},
    #     {'name': 'test2'},
    # ])

    # Example of setting all Many-To-Many Tags - WORKS
    # await post.set('tags', [
    #     tags['linux'],
    # ])

    # Example of deleting all Polymorphic Many-To-Many Hashtags - DELETE DOES NOT WORK FOR POLY MTM (as currently designed)
    #await post.delete('hashtags')

    # Example of deleting all One-To-Many comments - DELETE DOES NOT WORK FOR OTM (as currently designed)
    #await post.delete('comments')

    # Example of deleteing a HasOne child - WORKS
    #post = await Post.query().find(1)
    #await post.delete('image')

    # Example of linking Polymorphic Many-To-Many Hashags - WORKS
    # await post.link('hashtags', [
    #     hashtags.get('obsolete')
    # ])

    # Example of linking tags (does not create, only links EXISTING tags) - WORKS
    # await post.link('tags', [
    #     # Linking can be EXISTING Dict
    #     # {
    #     #     'id': 1,
    #     #     'name': 'linux',
    #     #     'creator_id': 1,
    #     # }
    #     # Or existing Model
    #     tags.get('linux'),
    #     tags.get('mac'),
    #     tags.get('bsd'),
    # ])

    # Test unlink
    # await post.unlink('tags', tags.get('linux'))  # As not list
    # await post.unlink('tags', [tags.get('mac')])  # As list
    # await post.unlink('tags') # All

    # Create (if not exists) AND link tags
    # await post.create('tags', [
    #     tags['linux'],  # Already exists, won't re-create
    #     Tag(id=1, name='linux', creator_id=1),  # Already exists, should just link
    #     Tag(name='test1', creator_id=4),  # Does not exist, should create and link
    #     {
    #         'name': 'test2',
    #         'creator_id': 4,
    #     }
    # ])

    #post.create()

    # Show Attributes
    #post.attributes

    # Create and link attributes
    #post.create('attributes', [{'key': 'asdf', 'value': 'asdf'}])

    # Delete and unlink attributes
    # post.delete('attributes')  # all
    # post.delete('attributes', [attribute1, attribute2]) # by model
    # post.delete('attributes', 'key1', 'key2')  # not by pk, but secondary pk the "key" column somehow

    # contacts table for a One-To-One Poly
    # combined PK of table_name + table_pk for unique (so could get rid of ID column technically)
    # id  | table_name | table_pk | name    | email | phone
    # ------------------------------------------------------
    # 1   | users      | 1        | Matthew | @asdf | 555
    # 2   | employee   | 4        | Bob     | @asdf | 444

    # attributes table for a One-To-Many Poly
    # Only unique has to be ID column, or I suppose a combo of table_name+table_pk+key would do it, would also be the composit index
    # Then could get rid of ID column
    # id  | table_name | table_pk | key  | value
    # -------------------------------------------
    # 1   | users      | 1        | name | matthew
    # 2   | users      | 1        | age  | 37

    # poly_tags pivot table for a Many-To-Many Poly
    #     entity_tags
    #     poly_tags
    #     tag_relations
    #     tag_linkage
    # post_id | tag_id |
    # table_name | table_pk | tag_id
    # ------------------------------
    # posts      | 1        | 5
    # posts      | 1        | 6
    # comments   | 23       | 5
    # comments   | 23       | 7

    # NO, add does not exist.  Use create to make/link or link to just link
    # .add() = create record and linkage
    #post.query('attributes').add({'key': 'value'})

    # this works NOW - it creates and links
    #post.create('comments', ['asdf'])

    # So this should create a tag and link it
    #post.create('tags', ['tag1...])

    # Easier than .tags()
    # Link and unlink should be ONLY for ManyToMany
    # Because all othe relations the ID is a foreing key on one of the tables
    # So to unlink it, you have to DELETE the record, there is no "link"

    # post.link('tags', tags)
    # post.unlink('tags', tag[0]) #unlink one tag
    # post.unlink('tags')  # unlink all tags

    # You can insert one so you can insert relations right after
    post = await Post(
        slug='test-post2',
        title='Test Post2',
        body=
        'This is the body for test post2.  My favorite frameworks are Laravel and Uvicore!',
        other=None,
        creator_id=1,
        owner_id=2).save()
    # Create AND Link if nto exist Many-To-Many tags
    await post.link('tags', [
        tags['linux'],
        tags['bsd'],
    ])
    # Create Polymorphic One-To-One
    await post.create(
        'image',
        {
            #'imageable_type': 'posts',  # NO, inferred
            #'imageable_id': 2,  # NO, inferred
            'filename': 'post2-image.png',
            'size': 2483282
        })
    # Create Polymorphic One-To-Many
    # NOTE: .add is simplay an alias for .create()
    await post.add('attributes', [
        {
            'key': 'post2-test1',
            'value': 'value for post2-test1'
        },
        {
            'key': 'post2-test2',
            'value': 'value for post2-test2'
        },
        {
            'key': 'badge',
            'value': 'IT'
        },
    ])
    # Create Polymorphic Many-To-Many
    await post.add(
        'hashtags',
        [
            hashtags['obsolete'],
            hashtags['outdated'],
            hashtags[
                'outdated'],  # Yes its a duplicate, testing that it doesn't fail
        ])

    # You can NOT insert relations right away, these tags will be IGNORED
    # User Dict with insert_with_relations if you want this
    post = await Post(
        slug='test-post3',
        title='Test Post3',
        body=
        'This is the body for test post1.  I like the programming in PHP, Python and anything Typescript.',
        other='other stuff2-bad',  # We'll update this away below
        creator_id=2,
        owner_id=1,
        tags=[  # TAGS IGNORED
            tags['linux'],
            tags['bsd'],
        ]).save()

    # Test an update
    post.other = 'other stuff3'
    await post.save()
    await post.add('attributes', [
        {
            'key': 'badge',
            'value': 'DEV'
        },
    ])
    await post.add('hashtags', [
        hashtags['important'],
    ])

    # You can use .insert() as a List of model instances
    # But obviously you cant then add in tags
    # This WILL NOT insert relations at all
    await Post.insert([
        # 2 posts for admin
        #Post(slug='test-post1', title='Test Post1', other='other stuff1', creator_id=1),
        #Post(slug='test-post2', title='Test Post2', other=None, creator_id=1, owner_id=2),

        # 3 posts for manager1
        #Post(slug='test-post3', title='Test Post3', other='other stuff2', creator_id=2, owner_id=1),
        Post(
            slug='test-post4',
            title='Test Post4',
            body=
            'This is the body for test post1.  My favorite morotcycles are super fast crotch rockets!',
            other=None,
            creator_id=2,
            owner_id=1),
        Post(
            slug='test-post5',
            title='Test Post5',
            body='This is the body for test post1.  Everyone loves and cynic.',
            other=None,
            creator_id=2,
            owner_id=2),

        # 2 posts for user2
        #Post(slug='test-post6', title='Test Post6', other='other stuff3', creator_id=5),
        #Post(slug='test-post7', title='Test Post7', other=None, creator_id=5),
    ])

    # You can also user .insert() as a list of Dict
    # This one inserts BelongsTo children FIRST (user, then contact, then post)
    # This is a multi nesting deep insert (NOT bulk, in a loop because of relations)
    # Creates User First, then Contact Second, Then finally Post with new creator_id
    await Post.insert_with_relations([{
        'slug':
        'test-post6',
        'title':
        'Test Post6',
        'body':
        'This is the body for test post1.  Everyone wants to fly.',
        'other':
        'other stuff6',
        #NO - 'creator_id': 5,
        'creator': {
            'username': '******',
            'email': '*****@*****.**',
            'first_name': 'User',
            'last_name': 'Two',
            'creator_id': 2,
            'password': '******',
            'contact': {
                'name': 'User Two',
                'title': 'User2',
                'address': '444 User Dr.',
                'phone': '444-444-4444'
                # NO user_id=5
            },
            'info': {
                'extra1': 'user5 extra',
            },
        },
        'owner_id':
        3,

        # Polymorphic One-To-One
        'image': {
            'filename': 'post6-image.png',
            'size': 3345432,
        },

        # Polymorphic One-To-Many
        'attributes': [
            {
                'key': 'post6-test1',
                'value': 'value for post6-test1'
            },
            {
                'key': 'post6-test2',
                'value': 'value for post6-test2'
            },
            {
                'key': 'post6-test3',
                'value': 'value for post6-test3'
            },
            {
                'key': 'badge',
                'value': 'IT'
            },
            #{'key': 'test', 'value': 'Hi there, my name is matthew reschke, what is your name?  Again, my name is Matthew Reschke, what is your name?  Again, my name is Matthew Reschke, what is your name?'},
        ],

        # Polymorphic Many-To-Many
        'hashtags': [hashtags['outdated']],
    }])
    # This does NOT work yet, but would be nice.  Especially if it can UPDATE an existing child
    #post = await Post.query().find(6)
    # await post.add('creator', {
    #     'email': '*****@*****.**',
    #     'contact': {
    #         'name': 'User Two',
    #         'title': 'User2',
    #         'address': '444 User Dr.',
    #         'phone': '444-444-4444'
    #         # NO user_id=5
    #     },
    # })

    # You can insert a single model with .save()
    post = Post(
        slug='test-post7',
        title='Test Post7',
        body='This is the body for test post1.  I like the to code alone.',
        other=None,
        creator_id=5,
        owner_id=4)
    await post.save()
    await post.create('tags', [
        tags.get('linux'),
        tags.get('bsd'),
        tags.get('laravel'),
    ])