| Security Feature | Fabric Lakehouse (March 2025) | Fabric Warehouse |
|---|---|---|
| Object-Level Security | Yes – via SQL grants on schemas/tables (T-SQL) learn.microsoft.com. OneLake security roles also allow table/folder-level access control in preview. | Yes – via SQL grants on schemas/tables (T-SQL) learn.microsoft.com. Workspace role or item permission needed to connect. |
| Row-Level Security (RLS) | Yes – supported on Lakehouse SQL endpoint via SECURITY POLICY (same as Warehouse) learn.microsoft.com. In |
| Capability | Microsoft Fabric Lakehouse | Microsoft Fabric Warehouse | |---------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| // Create PRICE_HISTORY relationship between instrument and Price | |
| MATCH (i:Instrument), (p:Price) WHERE i.symbol = p.ticker | |
| MERGE (i)-[:PRICE_HISTORY {tradingDate:p.timestamp}]->(p) |
| // Create NEXT_PERIOD relationships | |
| call apoc.periodic.iterate("MATCH (i:Instrument) RETURN i.symbol as Symbol", | |
| "MATCH (price:Price {ticker:Symbol}) | |
| WITH price | |
| ORDER BY price.ticker, price.timestamp | |
| WITH collect(price) as prices | |
| FOREACH(i IN range(0, size(prices)-2) | | |
| FOREACH(price1 IN [prices[i]] | | |
| FOREACH(price2 IN [prices[i+1]] | | |
| MERGE (price1)-[:NEXT_PERIOD {priceGap:round(price2.open - price1.close,2)}]->(price2) |
| //Load Daily Price History for every Instrument | |
| CALL apoc.periodic.iterate("MATCH (i:Instrument) RETURN i.symbol as Symbol" | |
| , "CALL apoc.load.jsonParams('https://api.tdameritrade.com/v1/marketdata/'+ Symbol + '/pricehistory?apikey=' + 'YOUR_CONSUMER_KEY_GOES_HERE' + '&frequencyType=daily&periodType=year&frequency=1&endDate=' + timestamp() + '&startDate=' + dateTime('2022-04-01').epochMillis , {Authorization:" + '\''+$token[0].access_token+'\'' + "} ,null) | |
| YIELD value | |
| UNWIND value.candles AS cndl | |
| FOREACH (candle in cndl | MERGE (s:Price {ticker: value.symbol,timestamp: datetime.fromepochmillis(candle.datetime) }) | |
| ON CREATE SET | |
| s.open = candle.open, | |
| s.close = candle.close, | |
| s.volume = candle.volume, |
| // Load instrument and fundamental | |
| CALL apoc.periodic.iterate("UNWIND ['MSFT','SPY','TSLA','AAPL','QQQ','NFLX','NVDA'] AS Symbol RETURN Symbol" | |
| ,"CALL apoc.load.jsonParams('https://api.tdameritrade.com/v1/instruments?apikey='+ 'YOUR_CONSUMER_KEY_GOES_HERE' +'&symbol=' + Symbol + '&projection=fundamental',{Authorization:'$token[0].access_token' },null) | |
| YIELD value | |
| UNWIND value[Symbol] AS instrument | |
| UNWIND instrument.fundamental as fundamental | |
| MERGE (i:Instrument {symbol:instrument.symbol}) | |
| SET | |
| i.cusip=instrument.cusip, | |
| i.description=instrument.description, |
| // Parameterize the access bearer token | |
| :param token => {CALL apoc.load.jsonParams("https://api.tdameritrade.com/v1/oauth2/token",null,"client_id=YOUR_CONSUMER_KEY_GOES_HERE%40AMER.OAUTHAP&grant_type=refresh_token&refresh_token=" + apoc.text.urlencode("YOUR_90_DAY_REFRESH_TOKEN_GOES_HERE_FROM_PREVIOUS_STEP")) | |
| YIELD value | |
| RETURN "Bearer " + value.access_token as access_token} |
| // Generate New Refresh Token | |
| CALL apoc.load.jsonParams("https://api.tdameritrade.com/v1/oauth2/token",null,"grant_type=authorization_code&refresh_token=&access_type=offline&code=" + "Paste_Your_CODE_Here" + "&client_id=YOUR_CONSUMER_KEY_GOES_HERE %40AMER.OAUTHAP&redirect_uri=YOUR_CALLBACK_URL_GOES_HERE") | |
| YIELD value | |
| UNWIND value.refresh_token as refresh_token_90days | |
| //UNWIND value.access_token as access_token_30m | |
| RETURN refresh_token_90days //, access_token_30m |
| https://auth.tdameritrade.com/oauth?client_id=YOUR_CONSUMER_KEY_GOES_HERE%40AMER.OAUTHAP&redirect_uri=YOUR_CALLBACK_URL_GOES_HERE&response_type=code&lang=en-us |
| //Use Neo4j's jolt formating with the HTTP API to get properties | |
| //This Power Query uses Accept Header "application/vnd.neo4j.jolt" in the API Call, which makes for a cleaner and shorter PQ query | |
| let | |
| //Enter the base URL for the Neo4j Server | |
| __Neo4jURL = "http://localhost:7474", | |
| // Enter the name of the database in Neo4j | |
| __Neo4jDatabase = "blogs", | |
| // Enter the username for database access in the Neo4j database | |
| __Username = "neo4j", |