async def xtest_app1(app1): #print(app.providers) #dump(uvicore.app.providers) #dump(uvicore.db.connections) from app1.models.post import Post from uvicore.auth.models.user import User #dump(Post.info()) #metakey = 'sqlite:///:memory' users = await User.all() dump(users) # client = TestClient(uvicore.app.http.server) # #print(uvicore.app.http.server) # response = client.get('/app1/api/posts') # dump(response) #dump(client) #from uvicore.support import path #print(path.find_base(__file__) + '/testapp/app') assert 1 == 2
def _build_where(self, where_str: str) -> List[Tuple]: # If where_str is already a Dict (from a JSON blog) convert to str first if type(where_str) == dict: where_str = json.dumps(where_str) dump('where_str', where_str) wheres = [] if not where_str: return wheres try: # Convert where string JSON to python object where_json = json.loads(where_str) # Where must be a dict if not isinstance(where_json, dict): return # WORKS - where={"id": [">", 5]} # WORKS - where={"id": ["in", [1, 2, 3]]} # WORKS - where={"title": ["like", "%black%"]} # WORKS - where={"id": 65, "topic_id": ["in", [1, 2, 3, 4, 5]]} # WORKS - ?include=topic.section.space&where={"topic.slug": "/tools", "topic.section.slug": "/apps", "topic.section.space.slug": "/dev"} for (key, value) in where_json.items(): #dump("Key: " + str(key) + " - Value: " + str(value)) if isinstance(value, List): if len(value) != 2: continue # Valid advanced value must be 2 item List operator = value[0] value = value[1] #query.where(key, operator, value) wheres.append((key, operator, value)) else: #query.where(key, value) wheres.append((key, '=', value)) return wheres except Exception as e: #self.log.error(e) dump(e)
async def test_select_single_through_many_to_many(app1): from app1.models.post import Post # One User has One Contact (contact table has user_id as UNIQUE) # But done through a Post with Many-To-Many Tags # Fetch one post = await Post.query().include( 'tags', # This is the Many-To-Many 'tags.creator' # This is the One through the Many 'tags.creator.contact', # This is the One through the Many second level ).find(1) dump(post) assert [ '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', ] == ([x.creator.email for x in post.tags]) assert [ 'Anonymous', 'Anonymous', 'God', 'Manager2', 'Manager2', ] == [x.creator.contact.title for x in post.tags]
async def test_selects(app1): import sqlalchemy as sa from app1.database.tables.posts import Posts from app1.database.tables.users import Users from app1.database.tables.contacts import Contacts posts, users, contacts = Posts.table.c, Users.table.c, Contacts.table.c query = ( uvicore.db.query('app1').table(Posts.table).select( posts.id, posts.unique_slug, users.email, 'auth.users.app1_extra') # Test with table as real SQLAlchemy Table and columns as strings .join(Users.table, 'posts.creator_id', 'auth.users.id') # Test with string table and columns as real SQLAlchemy .join('contacts', users.id, contacts.user_id)) results = await query.get() print(query.sql()) dump(results) dump(results[0].keys()) # Notice no name collisions assert [(1, 'test-post1', '*****@*****.**', 'hi'), (2, 'test-post2', '*****@*****.**', 'hi'), (3, 'test-post3', '*****@*****.**', None), (4, 'test-post4', '*****@*****.**', None), (5, 'test-post5', '*****@*****.**', None), (6, 'test-post6', '*****@*****.**', None), (7, 'test-post7', '*****@*****.**', None)] == results
async def test_select_one(app1): from app1.models.post import Post post = await Post.query().include('tags').find(1) dump(post) assert post.slug == 'test-post1' assert ['linux', 'mac', 'bsd', 'test1', 'test2'] == [x.name for x in post.tags]
async def test_one_to_many_inverse(app1): from uvicore.auth.models.user import User from app1.models.post import Post from app1.models.comment import Comment # Many Posts have one Creator (Inverse of One-To-Many) posts = await Post.query().include('creator').get() dump(posts) assert [ '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', ] == [x.creator.email for x in posts] # Many Posts have One Comment (Inverse of One-To-Many) comments = await Comment.query().include('post').get() dump(comments) assert [ 'test-post1', 'test-post1', 'test-post3', 'test-post3', 'test-post3', ] == [x.post.slug for x in comments]
def test_get(app1): client = TestClient(uvicore.app.http.server) res = client.get("/app1/api/posts") assert res.status_code == 200, res.text data = res.json() dump(data) assert len(data) == 7 assert data[0] == { 'id': 1, 'slug': 'test-post1', 'title': 'Test Post1', 'body': 'This is the body for test post1. I like the color red and green.', 'other': 'other stuff1', 'cb': 'test-post1 callback', 'creator_id': 1, 'creator': None, 'owner_id': 2, 'owner': None, 'comments': None, 'tags': None, 'image': None, 'attributes': None, 'hashtags': None }
async def test_join(app1): import sqlalchemy as sa query = ( uvicore.db.query('app1').table('posts') # Test with table as real SQLAlchemy Table and columns as strings .join('auth.users', 'posts.creator_id', 'auth.users.id', alias='creator') # Test with string table and columns as real SQLAlchemy .join('contacts', 'auth.users.id', 'contacts.user_id', alias='creator__contact') # Test with SQLAlchemy Binary Expression .join('comments', 'posts.id', 'comments.post_id')) results = await query.get() print(query.sql()) dump(results) dump(results[0].keys()) # Notice no name collisions assert [ 'test-post1', 'test-post1', 'test-post3', 'test-post3', 'test-post3', ] == [x.unique_slug for x in results]
async def test_join2(app1): from sqlalchemy import select from app1.database.tables.posts import Posts from app1.database.tables.users import Users from app1.database.tables.contacts import Contacts from app1.database.tables.comments import Comments # This looks close to my own Db Query Builder but you have to manually .fetchall() # and the returned RowProxy has column name collisions. You would have to select # each column and add a .label() to avoid collisions. So my query builder is still # a lot simpler and a bit better looking. posts, users, contacts, comments = Posts.table, Users.table, Contacts.table, Comments.table query = (select([posts, users, contacts, comments]).select_from( posts.join(users, posts.c.creator_id == users.c.id).join( contacts, users.c.id == contacts.c.user_id).join( comments, posts.c.id == comments.c.post_id))) results = await uvicore.db.fetchall(query, connection='app1') dump(results) dump(results[0].keys()) # Notice name collissions assert [ 'test-post1', 'test-post1', 'test-post3', 'test-post3', 'test-post3', ] == [x.unique_slug for x in results]
async def test_select_all(app1): posts = (await uvicore.db.query().table('posts').get()) dump(posts) assert [ 'test-post1', 'test-post2', 'test-post3', 'test-post4', 'test-post5', 'test-post6', 'test-post7' ] == [x.unique_slug for x in posts]
async def test_join_group_by(app1): import sqlalchemy as sa from app1.database.tables.posts import Posts # In order to use any raw SQLAlchemy function, you must get the actual table # This is a hybrid because of the count(), but we want to test a STRING order_by posts = Posts.table.c query = (uvicore.db.query('app1') .table('posts') # Test with table as real SQLAlchemy Table and columns as strings .join('auth.users', 'posts.creator_id', 'auth.users.id', alias='creator') # Select nested field and count() # Testing both relation dot and __ notation .select('creator.email', 'creator__first_name', sa.func.count(posts.id)) # Group by nested field .group_by('creator.email', 'creator__first_name') ) results = await query.get() print(query.sql()) dump(results) dump(results[0].keys()) assert [ ('*****@*****.**', 'Admin', 3), ('*****@*****.**', 'Anonymous', 2), ('*****@*****.**', 'User', 1), ('*****@*****.**', 'User', 1) ] == results
async def test_join_order_by(app1): query = (uvicore.db.query('app1') .table('posts') # Test with table as real SQLAlchemy Table and columns as strings .join('auth.users', 'posts.creator_id', 'auth.users.id', alias='creator') # Order by using nested dot notation .order_by('creator.email', 'DESC') ) results = await query.get() print(query.sql()) dump(results) dump(results[0].keys()) assert [ 'test-post6', 'test-post7', 'test-post1', 'test-post2', 'test-post3', 'test-post4', 'test-post5', ] == [x.unique_slug for x in results] assert [ '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', ] == [x.creator__email for x in results]
async def test_join_orwhere(app1): import sqlalchemy as sa query = (uvicore.db.query('app1') .table('posts') # Test with table as real SQLAlchemy Table and columns as strings .join('auth.users', 'posts.creator_id', 'auth.users.id', alias='creator') # Or where using both dot and __ notation .or_where([ ('creator.email', '*****@*****.**'), ('creator__email', '*****@*****.**') ]) ) results = await query.get() print(query.sql()) dump(results) dump(results[0].keys()) # Notice no name collisions assert [ 'test-post3', 'test-post4', 'test-post5', 'test-post7', ] == [x.unique_slug for x in results] assert [ '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', ] == [x.creator__email for x in results]
def listeners(): """Show all event listeners/handlers""" log.header("Event listeners/handlers") log.line() #dump(uvicore.events.expanded_sorted_listeners) dump(uvicore.events.listeners)
def list(raw: bool = False): """List all deep merged configs from all packages""" if not raw: log.header("List of all deep merged configs from all packages") log.line() dump(uvicore.config) else: print(uvicore.config)
async def query_spaces(): from mreschke.wiki.models import Space spaces = await (Space.query().include('sections', 'sections.topics').where( 'sections.name', 'Production').order_by('order').sort( ['sections.order', 'sections.topics.order']).get()) dump(spaces) dump("DONE!")
async def test_where_not_like(app1): query = (uvicore.db.query('app1').table('posts').where( 'other', '!like', '%1')) results = await query.get() print(query.sql()) dump(results) dump(results[0].keys()) assert ['test-post3', 'test-post6'] == [x.unique_slug for x in results]
async def test_where_null(app1): query = (uvicore.db.query('app1').table('posts').where('other', 'null')) results = await query.get() print(query.sql()) dump(results) dump(results[0].keys()) assert ['test-post2', 'test-post4', 'test-post5', 'test-post7'] == [x.unique_slug for x in results]
async def test_select_inverse_single(app1): from app1.models.contact import Contact # One Contact has One User (contact table has user_id as UNIQUE) # Fetch one contact: ContactModel = await Contact.query().include('user').find(3) dump(contact) assert contact.user.email == '*****@*****.**'
async def test_or_where(app1): query = (uvicore.db.query('app1').table('posts').or_where([('id', '=', 1), ('id', 2)])) results = await query.get() print(query.sql()) dump(results) dump(results[0].keys()) assert ['test-post1', 'test-post2'] == [x.unique_slug for x in results]
def connections(): """Show all packages database connections""" log.header( "All deep merged database connections from all defined packages") log.line() log.notice( "Some connections share the same database which means their tables are in the same metedata space. This is what the unique metakey denotes." ) dump(db.connections)
async def db_play(): from uvicore import db from mreschke.wiki.models.post import Post from uvicore.auth.models.user import User # dump(db.default) # dump(db.connections) # dump(db.engines) # True Raw, matching SQLA Core # engine = db.engine('wiki') # con = engine.connect() # table = User.__table__ # query = table.select() # users = con.execute(query) # for user in users: # dump(user) # dump(user['name']) # dump(user.name) # dd(users) # Not so raw, no engine, no connection, using User entity # query = User.__table__.select() # users = db.execute(User, query) # for user in users: # dump(user) # dump(user['name']) # dump(user.name) # dd(users) # Model usage #dd(db.metadata.get('wiki').tables) #dd(User.__fields__['id'].field_info.extra['sortable']) #dd(User.info(True)) #dd(Post.find(1)) #x: Post = Post.find(1) #dd(x) from asgiref.sync import async_to_sync from time import sleep #engine = db.engine('wiki') #async_to_sync(engine.connect)() #engine.connect() #dd(Post.info()) posts: List[Post] = await Post.all() #posts = Post.include('creator').get() #for post in posts: #dd(post.creator) dump(posts)
async def post4( request: Request, user: UserInfo = Guard(['posts.read']) ) -> models.Post: """This docstring shows up in OpenAPI Docs""" #dump('=============================================================') #dump('REQUEST __dict__ FROM /post4 CONTROLLER:') #dump('=============================================================') #dump(request.__dict__) dump('POST4 User:', user) return await models.Post.query().find(4)
async def test_select_all(app1): from app1.database.tables.posts import Posts query = Posts.table.select() results = await uvicore.db.fetchall(query, connection='app1') dump(results) assert [ 'test-post1', 'test-post2', 'test-post3', 'test-post4', 'test-post5', 'test-post6', 'test-post7' ] == [x.unique_slug for x in results]
def singletons(): """List Singleton Ioc Bindings""" uvicore.log.header("List of all Ioc singleton bindings") uvicore.log.line() bindings = { key: binding for (key, binding) in uvicore.ioc.bindings.items() if binding.singleton == True } dump(bindings)
def __schema__(self): if __class__.__table__ is None: # Build SA table dump('building sa table') attributes = [x for x in dir(self) if '__' not in x] columns = [getattr(self, x) for x in attributes] __class__.__table__ = sa.Table( self.__tablename__, db.metadata.get(self.__connection__), *columns) return __class__.__table__
def metakey(self, connection: str = None, metakey: str = None) -> str: try: if not metakey: if not connection: connection = self.default metakey = self.connection(connection).metakey return metakey except Exception: dump("ERROR Connections:", self.connections) raise Exception('Metakey not found, connection={} metakey={}'.format(connection, metakey))
async def test_select_inverse_through_single(app1): from app1.models.contact import Contact # One Contact has One User (contact table has user_id as UNIQUE) # And that user has One Info # Fetch one contact = await Contact.query().include('user', 'user.info').find(3) dump(contact) assert contact.user.email == '*****@*****.**' assert contact.user.info.extra1 == 'user1 extra'
async def url_query(): where = """{ "id": 1, "name": ["like", "some name"], "email": ["in", ["one", "two"]] }""" dump('where=' + str(json.loads(where))) dump("DONE!")
async def test_where_in(app1): query = (uvicore.db.query('app1').table('posts').where( 'unique_slug', 'in', [ 'test-post1', 'test-post2', ])) results = await query.get() print(query.sql()) dump(results) dump(results[0].keys()) assert ['test-post1', 'test-post2'] == [x.unique_slug for x in results]