Generate dynamic GraphQL Schema - api

I'm creating a system where the no. of columns in a table is not fixed. I'll explain with an example.
Consider a people table with 3 columns.
people
----------
id | name | email
This table will be exposed to a GraphQL API and I can query the table. In my system, the user will be able to add custom columns to the people table. Let's say they add a nationality column. When they do this, the nationality won't be available in the API because it is not defined in the Schema.
So how can I make my schema dynamic that allows the user to query the people table with every extra column they add?

I can query the information_schema table or a fields table and get the extra fields for the people table and then use the GraphQLObjectType to build out my schema rather than using SDL.

this is not the answer to your question but the suggestion because creating dynamic columns in SQL doesn't look like a good idea to me. Instead of thinking how can you create dynamic schema I think you should rethink on your DB structure.
Instead of adding new columns in Person table you should have different table for your custom columns like create person_columns table like
person_columns
----------
id | people_id | column_name | column_value
so for every people you can have multiple columns and its corresponding values and you dont have to worry about dynamically creating your graphQL schema. (depending on your requirement you can add more columns to person_columns table for more control)

Related

How to determine if a column exists in SQL server DB in other tables with a different name

I need to fetch specific hardware data from source tables. The hardware information is present in a table Server_Data with columns as follows,
Server_ID, Server Property, Property_Value
65 Model Cisco 123
65 Name Cisco abc
I need to link this table with System table that has columns as follows,
System_ID, System_IP
1 10.20.30.40
I searched all tables in database but Server_ID column is present only in Server _Data table. Also, I searched all tables if there exists a table that links System_ID with Server_ID, but there is no such table.
I need to find if the Server_ID column is present in any other table with some other name (say Server_Key or just Key). Any help would be appreciated.
Only using SQL, there will not be a way to find an identical column in another table, especially if it has a different name. I think you would need to manually compare every column in every other table to that column to find a match.
If I were you I would start by running the following SP:
EXEC sp_fkeys 'Server_Data'
That will tell you if the Server_ID column is referencing any other table in the DB or not.

bigquery dataset design, multiple vs single tables for storing the same type of data

im planning to build a new ads system and we are considering to use google bigquery.
ill quickly describe my data flow :
Each User will be able to create multiple ADS. (1 user, N ads)
i would like to store the ADS impressions and i thought of 2 options.
1- create a table for impressions , for example table name is :Impressions fields : (userid,adsid,datetime,meta data fields...)
in this options of all my impressions will be stored in a single table.
main pros : ill be able to big data queries quite easily.
main cons: table will be hugh, and with multiple queries, ill end up paying too much (:
option 2 is to create table per ads
for example, ads id 1 will create
Impression_1 with fields (datetime,meta data fields)
pros: query are cheaper, data table is smaller
cons: todo big dataquery sometimes ill have to create a union and things will complex
i wonder what are your thoughts regarding this ?
In BigQuery it's easy to do this, because you can create tables per each day, and you have the possibility to query only those tables.
And you have Table wildcard functions, which are a cost-effective way to query data from a specific set of tables. When you use a table wildcard function, BigQuery only accesses and charges you for tables that match the wildcard. Table wildcard functions are specified in the query's FROM clause.
Assuming you have some tables like:
mydata.people20140325
mydata.people20140326
mydata.people20140327
You can query like:
SELECT
name
FROM
(TABLE_DATE_RANGE(mydata.people,
TIMESTAMP('2014-03-25'),
TIMESTAMP('2014-03-27')))
WHERE
age >= 35
Also there are Table Decorators:
Table decorators support relative and absolute <time> values. Relative values are indicated by a negative number, and absolute values are indicated by a positive number.
To get a snapshot of the table at one hour ago:
SELECT COUNT(*) FROM [data-sensing-lab:gartner.seattle#-3600000]
There is also TABLE_QUERY, which you can use for more complex queries.

stored procedure that returns in one row duplicate column names and converts 1->N to a string

I'm trying to put all the below in a single stored procedute that returns a single row because the data is up on Sql Azure and the rule for it is do everything in a single query with a single return.
I have the following tables:
Person (
PersonId
FirstName
...
)
CompanyDomains (
CompanyId
EmailDomain
)
Company (
CompanyId
CompanyName
Billing_PersonId
Admin_PersonId
...
)
I have two problems here. The first is I want to get all the elements of a Company row, and the 2 Person rows of data. That's easy with a join. But the columns for the 2 person columns will have duplicate names. I can do 'as' one by one, which is a pain as the database schema is still in a state of flux. Is there a global way to apply 'as' so all the columns brought in from Billing_PersonId get a Billing_ prepended to the column name and Admin_ prepended to the admin column name?
The second is there is a 1->N list of company domains. Is there a way to pull all those and add a column that is a single string that has "domain1;domain2;" in it? We have the distinct domains in the CompanyDomain table so we can quickly find the company that owns any domain. But a single string works fine when I'm reading the company in.
I know single SQL selects pretty well. But I've got very little experience with stored procedures (aside from calling them) and so what I'm asking here may be basic. If so, sorry. And again, this is for Sql Azure.
thanks - dave
If you are using Azure, then you application should be able to parse XML.
Write a stored procedure to join the three tables, select the data given an input like company id, and return an xml record containing information from all three.
Look at the following references.
FOR XML
http://msdn.microsoft.com/en-us/library/ms178107.aspx
CREATE PROCEUDRE
http://msdn.microsoft.com/en-us/library/ms187926.aspx
If you need more help, you need to post a simple schema with sample data.
USE MY EXAMPLE BELOW FOR SCHEMA + DATA
sql select a field into 2 columns
1 - Without detailed information, not one will be able to help you.
2 - Try it on your own. I can give you the answer but you will not learn anything.
Sincerely
John

How to check efficiently, if a substring exists : SQL Query

I have to do certain actions based on the decision if a sub string exists in a column.
For example my column 'LangCodes' have # separated values like en-us#ar-ae#in-id.
I can use the SQL in operator if I can convert the value in form like : 'en-us','ar-ae','in-id'.
For example select Col1 from Table1 where 'en-us' in (LangCodes)
Do I need to use replace function of SQL to accomplish this or any better way exists?
You cannot do this efficiently in SQL Server, because you are storing your data in a fashion not consistent with the use of relational databases. You need a separate correlation table that has columns id and LangCode, with one row per language code.
You can do what you want with string operations. Here is a typical way:
where '#'+LangCodes+'#' like '%#en-us#%'
This, however, cannot take advantage of an index on LangCodes.
The most efficient and best way to check your languages codes is to seperate them in your table.
Never, never, never store multiple values in one column!
This is how your tables could look like (just examples)
product table
-------------
id
name
language_code table
-------------------
id
name
product_language_code table
---------------------------
product_id
language_code_id

SQL query: have results into a table named the results name

I have a very large database I would like to split up into tables. I would like to make it so when I run a distinct, it will make a table for every distinct name. The name of the table will be the data in one of the fields.
EX:
A --------- Data 1
A --------- Data 2
B --------- Data 3
B --------- Data 4
would result in 2 tables, 1 named A and another named B. Then the entire row of data would be copied into that field.
select distinct [name] from [maintable]
-make table for each name
-select [name] from [maintable]
-copy into table name
-drop row from [maintable]
Any help would be great!
I would advise you against this.
One solution is to create indexes, so you can access the data quickly. If you have only a handful of names, though, this might not be particularly effective because the index values would have select almost all records.
Another solution is something called partitioning. The exact mechanism differs from database to database, but the underlying idea is the same. Different portions of the table (as defined by name in your case) would be stored in different places. When a query is looking only for values for a particular name, only that data gets read.
Generally, it is bad design to have multiple tables with exactly the same data columns. Here are some reasons:
Adding a column, changing a type, or adding an index has to be done times instead of one time.
It is very hard to enforce a primary key constraint on a column across the tables -- you lose the primary key.
Queries that touch more than one name become much more complicated.
Insertions and updates are more complex, because you have to first identify the right table. This often results in overuse of dynamic SQL for otherwise basic operations.
Although there may be some simplifications (security comes to mind), most databases have other mechanisms that are superior to splitting the data into separate tables.
what you want is
CREATE TABLE new_table
AS (SELECT .... //the data that you want in this table);