[{"content":" Hey, I\u0026rsquo;m Chris Albert.\nI got my start in IT doing system administration before moving into database administration back in 2010. That led me deep into the world of data engineering, and I spent a good chunk of my career in healthcare — working across independent hospitals and health systems of all sizes. I learned a ton about how data can make a real difference in those environments.\nIn 2022 I joined Travelers and shifted my focus to DevOps. These days I spend most of my time working on CI/CD pipelines, infrastructure as code, and the tooling that helps teams ship software more reliably. It\u0026rsquo;s been a fun evolution from managing databases to managing the systems that deliver them.\nThis blog is where I write about the things I\u0026rsquo;m learning and building — DevOps, data, software engineering, and whatever else catches my interest. Thanks for stopping by.\nLinkedIn GitHub ","permalink":"https://datawrights.com/about/","summary":"\u003cdiv class=\"about-layout\"\u003e\n  \u003cdiv class=\"about-content\"\u003e\n    \u003cp\u003e\u003cstrong\u003eHey, I\u0026rsquo;m Chris Albert.\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eI got my start in IT doing system administration before moving into database administration back in 2010. That led me deep into the world of data engineering, and I spent a good chunk of my career in healthcare — working across independent hospitals and health systems of all sizes. I learned a ton about how data can make a real difference in those environments.\u003c/p\u003e\n\u003cp\u003eIn 2022 I joined Travelers and shifted my focus to DevOps. These days I spend most of my time working on CI/CD pipelines, infrastructure as code, and the tooling that helps teams ship software more reliably. It\u0026rsquo;s been a fun evolution from managing databases to managing the systems that deliver them.\u003c/p\u003e","title":"About"},{"content":"Intro You have all your data ready to go. It has been cleansed and transformed to all your needs. Now you need to make it easy to consume by your target audience. In this scenario our users can be just about anyone. We need to make the data easy to access and even easier to navigate.\nChallenge accepted!\nTooling As the title suggests we are going to be using Streamlit to present our data. If you aren\u0026rsquo;t familiar with Streamlit I suggest you take a tour of their website or GitHub repo to see what they have to offer. I chose Streamlit because it offers the ability to get a small project like this off the ground very quickly. We will also be using Pandas, and this will all be running on Python 3.12.2.\npip install pandas pip install streamlit Setup We need several supporting functions to make this streamlit site work.\nFirst up is a simple function to load data from a file. You may notice there is a special Streamlit decorator on this function, you can find the details behind it here st.cache_data, but we are essentially using it to cache the data to speed up performance for the end user. Our data is stored in CSVs so using pandas read_csv makes this very easy.\n# Function to load the CSV file @st.cache_data def load_data(file): data = pd.read_csv(file) return data Next we have a function that can filter our dataset based on what the user has entered into the search bar we are going to have in our web app.\n# Function to filter data based on search query def filter_data(data, query): if query: return data[data.apply(lambda row: row.astype(str).str.contains(query, case=False).any(), axis=1)] return data Last but not least we have a function to handle our main page. This function has a little more to it than the others, but it isn\u0026rsquo;t very complicated.\nDisplay the page title by setting st.title\nUsing st.expander we create a help box that is expandable with info on how to use the site\nCreate a file selection drop down box using st.selectbox so our end users can pick which dataset they want to view\nLoad the data file selected\nPresent a search box using st.text_input and filter results if needed\nDisplay our data in a dataframe using st.dataframe\nAdd a download button using st.download_button so the user can download the dataset if desired\n# Main app content def show_main(): st.title(\u0026#34;Town Info\u0026#34;) # Help box with st.expander(\u0026#34;Help (How to use this site)\u0026#34;): st.markdown(\u0026#34;\u0026#34;\u0026#34; **How to use this app:** - **Select a dataset**: Choose a dataset from the dropdown menu - **Search**: Use the search box to filter data by entering keywords or phrases - **Sort**: Click on the column headers to change how the data is sorted \u0026#34;\u0026#34;\u0026#34;) # File selection selected_file = st.selectbox(\u0026#34;Select a dataset to view\u0026#34;, list(csv_files.keys())) file_path = os.path.join(dir_data, csv_files[selected_file]) # Load the CSV data data = load_data(file_path) # Search functionality search_query = st.text_input(\u0026#34;Search\u0026#34;) filtered_data = filter_data(data, search_query) # Display the dataframe with sortable and filterable columns st.dataframe(filtered_data, height=1000) # Allow the user to download the filtered data csv = filtered_data.to_csv(index=False) st.download_button( label=\u0026#34;Download data as CSV\u0026#34;, data=csv, file_name=\u0026#39;filtered_data.csv\u0026#39;, mime=\u0026#39;text/csv\u0026#39;, ) Last but not least we run our application.\n# Streamlit app def main(): st.sidebar.title(\u0026#34;Navigation\u0026#34;) page = st.sidebar.selectbox(\u0026#34;Select a page\u0026#34;, [\u0026#34;Main\u0026#34;, \u0026#34;About\u0026#34;]) if page == \u0026#34;Main\u0026#34;: show_main() elif page == \u0026#34;About\u0026#34;: show_about() if __name__ == \u0026#34;__main__\u0026#34;: main() End Result When we run this Streamlit application we get the magnificent site pictured below for our end users. Quick note, the screenshot is in dark mode. We have enabled the following features:\nSelectable list of datasets\nFilter dataset with search\nSort with interactive headers\nDownload dataset\n","permalink":"https://datawrights.com/posts/python-presenting-data-with-streamlit/","summary":"\u003ch2 id=\"intro\"\u003eIntro\u003c/h2\u003e\n\u003cp\u003eYou have all your data ready to go. It has been cleansed and transformed to all your needs. Now you need to make it easy to consume by your target audience. In this scenario our users can be just about anyone. We need to make the data easy to access and even easier to navigate.\u003c/p\u003e\n\u003cp\u003eChallenge accepted!\u003c/p\u003e\n\u003ch2 id=\"tooling\"\u003eTooling\u003c/h2\u003e\n\u003cp\u003eAs the title suggests we are going to be using \u003ca href=\"https://pypi.org/project/streamlit/\"\u003eStreamlit\u003c/a\u003e to present our data. If you aren\u0026rsquo;t familiar with Streamlit I suggest you take a tour of their \u003ca href=\"https://streamlit.io/\"\u003ewebsite\u003c/a\u003e or \u003ca href=\"https://github.com/streamlit/streamlit\"\u003eGitHub repo\u003c/a\u003e to see what they have to offer. I chose Streamlit because it offers the ability to get a small project like this off the ground very quickly. We will also be using \u003ca href=\"https://pandas.pydata.org/\"\u003ePandas\u003c/a\u003e, and this will all be running on Python 3.12.2.\u003c/p\u003e","title":"Python: Presenting Data with Streamlit"},{"content":"Intro True story, the town I live in recently had some issues around the town budget. As I started to get involved I wanted to look at the data provided by our Board of Finance. To my misfortune, I found myself trying to analyze data in a PDF. Trying to do any sort of analysis on it was time consuming and frustrating. To make the data useful I needed to extract data from PDF and into something more flexible, in this case a simple CSV will do. Here is a sample of what we are working with:\nTooling For this project we are going to use Pandas and Tabula. I also want to note I am using Python 3.12.2 for this project. To get Tabula up and running you will need to have Java 8+ installed as well. From there its fairly straight forward.\npip install pandas pip install tabula-py Setup First we are going to create a function that uses Tabula to extract data from our source PDF. I was pleasantly surprised by how simple this is to implement. Behold the ease of use:\ndef extract_tables_from_pages(pdf_path,page): # Extract table from specified page tables = tabula.read_pdf(pdf_path, pages=page, multiple_tables=True) # Check if result is empty if not tables: return None # Concatenate all tables from the specified pages into one DataFrame df = pd.concat(tables, ignore_index=True) return df Now that we have our function to extract data lets handle the rest of the groundwork:\nCreate an empty file with our headers\nSet the page range for the PDF that our data is in\nInitialize and empty data frame\n# Create file with headers headers = [\u0026#39;Description\u0026#39;, \u0026#39;FY24Budget\u0026#39;, \u0026#39;FY25Budget\u0026#39;, \u0026#39;Change\u0026#39;, \u0026#39;ChangePercent\u0026#39;] df = pd.DataFrame(columns=headers) csv_file_path = \u0026#39;budget_data.csv\u0026#39; df.to_csv(csv_file_path, index=False) # Set page range start_page = 93 end_page = 98 # Initialize an empty DataFrame df = pd.DataFrame() With that out of the way lets put it to us:\nCall the function we created earlier, load the data into a data frame and add the proper column headers to it\nThe PDF sample has a bunch of summary rows on the last page of data so we check if its the last page and remove those rows if it is\nSince this PDF has a bunch of white space in it Tabula returns several columns that are meaningless, we need to drop all of those\nThe last modification we need to make is removing whitespace from columns with data we need\nIn the end we write the data frame to a CSV and we are all set\npdf_path = \u0026#39;C:\\\\Board_of_Finance_Budget.pdf\u0026#39; for page in range(start_page, end_page + 1): # Extract tables from the specified range of pages df = extract_tables_from_pages(pdf_path, page) new_row = pd.DataFrame([df.columns], columns=df.columns) df = pd.concat([new_row, df]).reset_index(drop=True) # Remove last 6 rows if last page if page == end_page: df = df.iloc[:-6] # Drop 2nd column df.drop(df.columns[1], axis=1, inplace=True) # Drop 3rd column df.drop(df.columns[2], axis=1, inplace=True) # Drop 4th column df.drop(df.columns[3], axis=1, inplace=True) # Remove space characters in the 2nd column df.iloc[:, 1] = df.iloc[:, 1].astype(str).str.replace(\u0026#39; \u0026#39;, \u0026#39;\u0026#39;) # Remove space characters in the 3rd column df.iloc[:, 2] = df.iloc[:, 2].astype(str).str.replace(\u0026#39; \u0026#39;, \u0026#39;\u0026#39;) if df is not None: # Print the DataFrame print(df) # Save the DataFrame to CSV df.to_csv(csv_file_path, mode=\u0026#39;a\u0026#39;, index=False, header=False) print(f\u0026#34;DataFrame saved to {csv_file_path}\u0026#34;) else: print(f\u0026#39;No table found on page {page}\u0026#39;) Wrapping Up With a small amount of effort we were able to extract several pages of detail data from a PDF and write it out to a CSV. I am very excited about the flexibility Tabula has brought to the table. For your needs you may be able to get away with less transformation than I had to do. I found in my research if a table in a PDF has lines outlining its columns the extraction is much easier. Let me know in the comments how you plan to use Tabula to extract data.\n","permalink":"https://datawrights.com/posts/python-extract-data-from-pdf/","summary":"\u003ch2 id=\"intro\"\u003eIntro\u003c/h2\u003e\n\u003cp\u003eTrue story, the town I live in recently had some issues around the town budget. As I started to get involved I wanted to look at the data provided by our Board of Finance. To my misfortune, I found myself trying to analyze data in a PDF. Trying to do any sort of analysis on it was time consuming and frustrating. To make the data useful I needed to extract data from PDF and into something more flexible, in this case a simple CSV will do. Here is a sample of what we are working with:\u003c/p\u003e","title":"Python: Extract Data From PDF"},{"content":"Intro In our last post we used SQLAlchemy to bulk load data into SQL Server. Now that we can bulk load data we want to perform other actions on our database. In todays post we want follow a common loading strategy and TRUNCATE the target table before loading it. Adding this functionality to our script leaves us with a choice to make in how we want to execute our SQL statements and manage database transactions.\nTransaction Management Using SQLAlchemy we have a couple different options to manage our transactions. The first option is their commit as you go approach with Connection.commit(). The second option is begin once with Engine.begin().\nConnection.commit() To get started we need to add a new import. SQLAlchemy text will prepare our SQL Statement to pass to the connection.\nfrom sqlalchemy import text Once we have the import in place we are going to create a new function to execute a passed in SQL statement. Here is a breakdown of what our new function is doing:\nUse the text() function to prepare out SQL statement\nEstablish a connection to the database\nExecute the SQL statement\nCommit the transaction\ndef execute_statement(sql_statement): try: sql = text(sql_statement) with engine.connect() as connection: connection.execute(sql) connection.commit() except Exception as e: print(f\u0026#34;Error occurred: {e}\u0026#34;) Now all we have to do is call the function before loading our dataset.\nsql_statement = \u0026#39;TRUNCATE TABLE dbo.CT_Real_Estate;\u0026#39; execute_statement(sql_statement) The entire script can be found on GitHub.\nEngine.begin() This method is slightly easier to implement for our use case. We don\u0026rsquo;t require any additional imports for this to work so we can jump right into writing our function. The function is also simpler because it can simply take in a string and execute it against the target server. We don\u0026rsquo;t need an explicit commit because this method automatically commits the transaction for us.\ndef execute_statement(sql_statement): try: # Execute SQL Statement with engine.begin() as con: con.exec_driver_sql(sql_statement) except Exception as e: print(f\u0026#34;Error occurred: {e}\u0026#34;) The entire script can be found on GitHub.\nDifferences For Connection.commit() you need to import text from SQL Alchemy and format your SQL statement with it before executing the statement.\nYou need to have an additional line of code to commit the transaction with Connection.commit().\nWrapping Up For our use case I chose to use Engine.Begin(). Our use case is fairly small so I like that I can keep my codebase to a minimum and skip the extras that Connection.commit() requires. For more advanced use cases where transaction handling plays a bigger role I would definitely reconsider these options.\n","permalink":"https://datawrights.com/posts/python-sql-server-manage-database-transactions/","summary":"\u003ch2 id=\"intro\"\u003eIntro\u003c/h2\u003e\n\u003cp\u003eIn our \u003ca href=\"https://dataartisans.tech/python-sql-server-bulk-loading-data/\"\u003elast post\u003c/a\u003e we used \u003ca href=\"https://www.sqlalchemy.org/\"\u003eSQLAlchemy\u003c/a\u003e to bulk load data into SQL Server. Now that we can bulk load data we want to perform other actions on our database. In todays post we want follow a common loading strategy and \u003ca href=\"https://learn.microsoft.com/en-us/sql/t-sql/statements/truncate-table-transact-sql?view=sql-server-ver16\"\u003eTRUNCATE\u003c/a\u003e the target table before loading it. Adding this functionality to our script leaves us with a choice to make in how we want to execute our SQL statements and manage database transactions.\u003c/p\u003e","title":"Python \u0026 SQL Server: Manage Database Transactions"},{"content":"Intro You have a bunch of data and need to load it into SQL Server using Python. With the abundance of options out there its difficult to know what the best tool is to use. Lets approach the problem with two requirements. The solution needs to be easy to implement and blazing fast.\nTooling Initially bcpandas looked like a great solution for this task. While it does fit our two requirements, it becomes very difficult to work with for data that contains multiple separators or any odd strings. If the data you work with is like mine it is almost never perfect. I quickly pivoted away from this due to its inability to handle imperfect data.\nTo get this job done we are going to use pandas, SQLAlchemy, and pyodbc. pandas is the Python go to for most data operations. It allows us to easily read in a large dataset and transform it as needed. pyodbc provides a fast easy way to connect to our SQL Server database. Using SQLAlchemy we have a robust toolset at our disposal for interacting with a database.\nEasy to Implement Getting our tooling up and running is a very simple exercise, especially if SQL Server is installed on the machine you are running the python script on. All we need from the SQL Server side of things is Microsoft ODBC Driver 11, 13, 13.1, or 17 for SQL Server. If SQL Server is installed locally you will already have these requirements satisfied. If not use the links to go download these requirements.\nFor our Python environment you need to meet the following requirements:\n2. pandas\n3. sqlalchemy\n4. pyodbc\nAssuming you already have python installed the rest of the setup is fairly straightforward.\npip install pandas pip install sqlalchemy pip install pyodbc Setup For our test dataset I went in search of something with a reasonable size. To my surprise one of the most popular datasets on data.gov is real estate sales from my home state of Connecticut. At just shy of one million records and 105MB in size it works as a great test dataset for our bulk data load.\nLets write out Python script:\nImport pandas and SQLAlchemy\nimport pandas as pd from sqlalchemy.engine import create_engine, URL Create a SQLAlchemy connection URL and engine\nconnect_url = URL.create( \u0026#39;mssql+pyodbc\u0026#39;, username=\u0026#34;\u0026lt;your username\u0026gt;\u0026#34;, password=\u0026#34;\u0026lt;your password\u0026gt;\u0026#34;, host=\u0026#34;\u0026lt;your server name\u0026gt;\u0026#34;, database=\u0026#34;\u0026lt;your database name\u0026gt;\u0026#34;, query=dict(driver=\u0026#39;ODBC Driver 17 for SQL Server\u0026#39;)) engine = create_engine( url=connect_url, fast_executemany=True, ) Test the connection\ntry: with engine.connect() as connection: print(\u0026#34;Connection successful!\u0026#34;) except Exception as e: print(f\u0026#34;Error occurred: {e}\u0026#34;) Load the real estate dataset we downloaded\ndf = pd.read_csv (\u0026#39;C:\\\\Real_Estate_Sales_2001-2020_GL.csv\u0026#39;, low_memory=False) Load the data into SQL Server\ndf.to_sql(con=engine, schema=\u0026#34;dbo\u0026#34;, name=\u0026#34;\u0026lt;target table\u0026gt;\u0026#34;, if_exists=\u0026#34;replace\u0026#34;, index=False, chunksize=1000) Blazing Fast Putting this all together I executed the script 5 times to see what our average performance looks like. Below are the executions and their time in seconds, average is 71.6 seconds. Not bad for 1 million records being read from a 150 MB csv.\n63\n72\n70\n83\n70\n","permalink":"https://datawrights.com/posts/python-sql-server-bulk-loading-data/","summary":"\u003ch2 id=\"intro\"\u003eIntro\u003c/h2\u003e\n\u003cp\u003eYou have a bunch of data and need to load it into SQL Server using Python. With the abundance of options out there its difficult to know what the best tool is to use. Lets approach the problem with two requirements. The solution needs to be \u003cstrong\u003eeasy to implement\u003c/strong\u003e and \u003cstrong\u003eblazing fast\u003c/strong\u003e.\u003c/p\u003e\n\u003ch2 id=\"tooling\"\u003eTooling\u003c/h2\u003e\n\u003cp\u003eInitially \u003ca href=\"https://pypi.org/project/bcpandas/\"\u003ebcpandas\u003c/a\u003e looked like a great solution for this task. While it does fit our two requirements, it becomes very difficult to work with for data that contains multiple separators or any odd strings. If the data you work with is like mine it is almost never perfect. I quickly pivoted away from this due to its inability to handle imperfect data.\u003c/p\u003e","title":"Python \u0026 SQL Server: Bulk Loading Data"},{"content":"Intro Back in August HashiCorp switched Terraforms license from Mozilla Public License v2.0 (MPL 2.0) to a Business Source License. In response, the open source community has forked the last MPL release of Terraform to a new project named OpenTofu. To understand their mission checkout the The OpenTofu Manifesto.\nCurrent State OpenTofu has an alpha release out if you want to take it for a test drive. I did so myself with a few sample projects and they all worked without any issues. Biggest difference so far is using tofu apply instead of terraform apply in the CLI.\nThere is a good amount of activity on the new open source repo. There is one pull request I am particularly excited about. Most folks who have worked with Terraform for any period of time have felt the pain of storing sensitive values in state. This PR aims to add the option to encrypt local state files, remote state, and plan files. Encryption is off-by-default. Keep pace with the conversation here.\nClosing Lots of exciting things are happening. I am very optimistic about where OpenTofu is heading. You should check it out and if you are interested contribute to the project.\n","permalink":"https://datawrights.com/posts/opentofu/","summary":"\u003ch2 id=\"intro\"\u003eIntro\u003c/h2\u003e\n\u003cp\u003eBack in August \u003ca href=\"https://www.hashicorp.com/blog/hashicorp-adopts-business-source-license\"\u003eHashiCorp switched Terraforms license\u003c/a\u003e from Mozilla Public License v2.0 (MPL 2.0) to a Business Source License. In response, the open source community has forked the last MPL release of Terraform to a new project named \u003ca href=\"https://opentofu.org/\"\u003eOpenTofu\u003c/a\u003e. To understand their mission checkout the \u003ca href=\"https://opentofu.org/manifesto\"\u003eThe OpenTofu Manifesto\u003c/a\u003e.\u003c/p\u003e\n\u003ch2 id=\"current-state\"\u003eCurrent State\u003c/h2\u003e\n\u003cp\u003e\u003ca href=\"https://github.com/opentofu/opentofu/releases/tag/v1.6.0-alpha3\"\u003eOpenTofu has an alpha release\u003c/a\u003e out if you want to take it for a test drive. I did so myself with a few sample projects and they all worked without any issues. Biggest difference so far is using \u003ccode\u003etofu apply\u003c/code\u003e instead of \u003ccode\u003eterraform apply\u003c/code\u003e in the CLI.\u003c/p\u003e","title":"OpenTofu"},{"content":"Intro With the exciting new announcement for Terraform Tests I couldn\u0026rsquo;t help but take them for a test drive. For our use case we will build on a prior post Terraform Azure: Reusable SQL Database Configurations. In the last post we created a module to deploy SQL Servers. Today we will add a new default prefix to SQL Server name and then build a test to check the name of the server.\nUpdate SQL Server Module We have decided we want all of our SQL Servers to have a standard prefix in their name. For Data Artisans we want to use the prefix dart-. To update the module with this functionality we can use string interpolation.\nDevelop Test First thing we want to do is create a new tests folder to store our tests in. Inside of that folder create a new file named sql_server.tftest.hcl. The .tftest.hcl file extension is what Terraform uses to recognize a test file.\nOnce that\u0026rsquo;s done we can write out test.\nCreate a variable for all of the inputs needed to successfully call the module. For the SQL Server module we need the 4 variables listed below.\nInitialize the provider needed to establish the resources we want to test.\nThe last thing we need is called a run block. These are used in tests to control the order you want different code executed. You can have one or many run blocks in a given test.\nSpecify the module we want to call in our test.\nUsing assertions we can write out the specific condition we want to test for once the module has been successfully executed. In our use case we want to test that the SQL Server created has the name dart-tf-test.\nRun Test When we run our test Terraform will create the defined resources, check our assertions, and then tear down the resources. To do this we use test command.\nA successful run will show the tests passed like below.\nTo simulate a failure I changed the expected name in our assertion. An unsuccessful run will show the tests failed, output the error we specified in the assertion, and it also gives us the unexpected value.\nClosing Thoghts I like the new testing framework in Terraform 1.6. It gives us a great set of tools to setup standard tests. Could we have accomplished this specific use case by running a plan and inspecting the values? Sure we could. What I really like here is that it actually creates the resources and tests what was created. A plan can show success, but the apply can still fail. Having the rubber hit the road here is where I see the value.\nYou can go follow the tutorial Hashicorp published for another use case example.\n","permalink":"https://datawrights.com/posts/terraform-azure-tests/","summary":"\u003ch2 id=\"intro\"\u003eIntro\u003c/h2\u003e\n\u003cp\u003eWith the exciting new announcement for \u003ca href=\"https://developer.hashicorp.com/terraform/language/tests\"\u003eTerraform Tests\u003c/a\u003e I couldn\u0026rsquo;t help but take them for a test drive. For our use case we will build on a prior post \u003ca href=\"https://dataartisans.tech/terraform-azure-reusable-sql-database-configurations/\"\u003eTerraform Azure: Reusable SQL Database Configurations\u003c/a\u003e. In the last post we created a module to deploy SQL Servers. Today we will add a new default prefix to SQL Server name and then build a test to check the name of the server.\u003c/p\u003e","title":"Terraform Azure: Tests"},{"content":"Intro In this post we will cover how to import an existing Azure SQL Database to Terraform. If the resource wasn’t originally created by Terraform you will need to import it before Terraform can manage it. This comes in handy when you have existing infrastructure and want to start using Terraform later on.\nFor a video walkthrough check out my YouTube video.\nHere we will use the standard import functionality provided by Terraform. There are other 3rd party tools you can use for this process as well. One of the most popular is Terraformer, I will cover how to use that in a later post.\nPrerequisites In a previous post on creating an Azure SQL Database, we deployed a Resource Group, SQL Server, and SQL Database. Today we will create a new project and import those existing resources so we can manage them with Terraform.\nThe import command will not reverse engineer your cloud infrastructure to Terraform for you. What the import command does is generate the state file for you. If you start with Terraform and deploy infrastructure, a state file is maintained along the way. When you start using Terraform after you already have infrastructure, you need to import it so Terraform can manage it.\nDefine Resources We need to create our main.tf file same as we did in the previous post. This is just like creating any normal Terraform from scratch. Code for this file can be found in my GitHub repo.\nImport Resources Now to import the Azure resources into the Terraform state file. In the first part of the import command we define a resource type and its name. We can pull this directly from our resource in the Terraform code. The second part we can copy and paste from the URL of our Azure resource. Simply navigate to the resource in the Azure portal and you should see the pattern in the URL.\nFirst up is the resource group.\nHere is the resource group in the main.tf file. We need the resource type and name.\nHere is the resource group in the Azure Portal. We need to copy everything from subscriptions to the last forward slash.\nUsing the info from both we create the import command to run.\nResource Group\nterraform import \u0026quot;azurerm_resource_group.rg-terraform\u0026quot; \u0026quot;/subscriptions/xxxxxxxxxxxxx/resourceGroups/rg-terraform\u0026quot;\nSQL Server\nterraform import \u0026quot;azurerm_mssql_server.sql-server-terraform\u0026quot; \u0026quot;/subscriptions/xxxxxxxxxxxxx/resourceGroups/rg-terraform/providers/Microsoft.Sql/servers/sql-server-terraform\u0026quot;\nSQL Database\nterraform import \u0026quot;azurerm_mssql_database.db-terraform\u0026quot; \u0026quot;/subscriptions/xxxxxxxxxxxxx/resourceGroups/rg-terraform/providers/Microsoft.Sql/servers/sql-server-terraform/databases/db-terraform\u0026quot;\nWrapping Up Now that we have imported our resources we need to test to make sure Terraform sees everything and doesn\u0026rsquo;t want to make any changes.\nRun terraform plan\nThe result should be no changes\nYou have successfully imported your Azure SQL Database to Terraform.\n","permalink":"https://datawrights.com/posts/terraform-azure-import-sql-database/","summary":"\u003ch2 id=\"intro\"\u003e\u003cstrong\u003eIntro\u003c/strong\u003e\u003c/h2\u003e\n\u003cp\u003eIn this post we will cover how to import an existing Azure SQL Database to Terraform. If the resource wasn’t originally created by Terraform you will need to import it before Terraform can manage it. This comes in handy when you have existing infrastructure and want to start using Terraform later on.\u003c/p\u003e\n\u003cp\u003eFor a video walkthrough check out my \u003ca href=\"https://youtu.be/y5tkKoGFXCk\"\u003eYouTube video\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eHere we will use the \u003ca href=\"https://developer.hashicorp.com/terraform/cli/import\"\u003estandard import functionality\u003c/a\u003e provided by Terraform. There are other 3rd party tools you can use for this process as well. One of the most popular is \u003ca href=\"https://github.com/GoogleCloudPlatform/terraformer\"\u003eTerraformer\u003c/a\u003e, I will cover how to use that in a later post.\u003c/p\u003e","title":"Terraform Azure: Import SQL Database"},{"content":"Intro In this post we are going to build on the previous post Terraform Azure: SQL Database. We will cover how you can use Terraform to create multiple Azure SQL Databases with Terraform modules. We are going to turn the original Terraform into a module so we can create as many databases as we need with identical configurations. Another advantage here is maintenance, if a setting needs to be adjusted you can simply adjust the module and it will propagate to each resource using the module configuration.\nOur goal is to create identical Azure SQL Databases on each coast of the United States. Using our module we will deploy 1 instance in region East US 2 and another in West US 2.\nPrerequisites To create a SQL Database you will need a user to assign admin privileges to. To create a user follow these instructions. If you already have one then you are all set. What we will need from the user is its name and the object id.\nAs you go through the sections of this post you will see screenshots of the code with callouts that I will walk through. You can find all the code for this example on my GitHub repo.\nGetting Started Start off by creating a new project, I named mine sql_db_template. In your project add the following.\nCreate a file named main.tf\nCreate a new folder named modules\nInside the modules folder create 2 folders, azure_sql_db and azure_sql_server\nInside the azure_sql_db folder create 2 files, main.tf and variables.tf\nInside the azure_sql_server folder create 3 files, main.tf, outputs.tf, and variables.tf\nCreating the SQL Server Module Our SQL Server Module will be in the azure_sql_server folder. I find it easiest to start with the main.tf file. Starting here we can easily identify what resource properties we want to create variables for.\nNext we go into the variables.tf file. Here we define each of the variables we identified in main.tf. This includes the variable type and description.\nLast we need to define the outputs we want from the module in the outputs.tf file. The outputs defined in this file are what our module will return after being called. For this module we only need the id of the server returned. This is needed so we can assign database resources to the server.\nCreating the SQL Database Module The SQL Database module will be in the azure_sql_db folder and we will again start with the main.tf file. Here we define the variables for the database resource.\nThen we define the variables.\nThis module doesnt have an outputs file because we dont need to pass any of its information to anything. An outputs file can be added in the future should we need something though.\nUsing the Modules Now we are going to dive into the main.tf file in the project folder. We will use the modules we just defined to create identical resources in separate azure regions.\nazurerm is the name of the Terraform Azure provider\nThis is required to configure the provider\nCreate a Resource Group in East US 2\nCreate a Resource Group in West US 2\nNow that we have our resource groups created we can call the SQL Server module to create a server in each group.\nDefine the module call\nProvide the path to the folder containing the SQL Server module\nGive the server a name\nReference to the name of the resource group this server will be in\nReference to the azure region of the resource group this server will be in\nUsername of the admin user account\nObjectId of the admin user account\nThe environment to tag this resource with\nWith the servers established we can now create the SQL Databases.\nDefine the module call\nProvide the path to the folder containing the SQL Database module\nGive the database a name\nReference the Id of the server the database will belong to. This is where the output we added to the SQL Server module comes in.\nThe environment to tag this resource with\nReady for Deployment With everything we have added to our project we are now ready to deploy our resources. If you run terraform apply you will deploy a SQL Server and SQL Database to East US 2 and West US 2.\n","permalink":"https://datawrights.com/posts/terraform-azure-reusable-sql-database-configurations/","summary":"\u003ch2 id=\"intro\"\u003e\u003cstrong\u003eIntro\u003c/strong\u003e\u003c/h2\u003e\n\u003cp\u003eIn this post we are going to build on the previous post \u003ca href=\"https://dataartisans.tech/terraform-azure-sql-database/\"\u003eTerraform Azure: SQL Database\u003c/a\u003e. We will cover how you can use Terraform to create multiple \u003ca href=\"https://azure.microsoft.com/en-us/products/azure-sql/database/\"\u003eAzure SQL Databases\u003c/a\u003e with \u003ca href=\"https://developer.hashicorp.com/terraform/language/modules/develop\"\u003eTerraform modules\u003c/a\u003e. We are going to turn the original Terraform into a module so we can create as many databases as we need with identical configurations. Another advantage here is maintenance, if a setting needs to be adjusted you can simply adjust the module and it will propagate to each resource using the module configuration.\u003c/p\u003e","title":"Terraform Azure: Reusable SQL Database Configurations"},{"content":"Intro In this post we are going to deploy a SQL Server VM in Azure. Deploying a VM requires a little more work than the SQL Database we deployed in the last post. We will need to add some networking resources and configure the host VM. If you need help setting up Terraform please see my prior post, Terraform Azure: Setting Up Your Environment. This post assumes you have an Azure account. If you do not, you can create one for free.\nAs you go through the sections of this post you will see screenshots of the code with callouts that I will walk through. You can find all the code for this example on my GitHub repo.\nGetting Started Fire up your favorite code editor, in this post I will be using VS Code\nStart a new folder for your project, mine is named sql-vwm\nCreate new files named main.tf and networking.tf\nThe Provider \u0026amp; Resource Group Up first is the Azure provider. You can find all the docs here. The code below will configure your project to pull the Azure provider and configure it.\nazurerm is the name of the Terraform Azure provider\nWe are using version 3.0 or better\nThis is required to configure the provider\nOur resource group will be named rg-terraform\nI have set the Azure region for this to East US 2. You can set it to whatever region you prefer.\nNetworking To stay focused on the details of SQL Server I am not going to deep dive into the networking resources required. See the networking.tf file in the repo to get a copy of all the resources.\nOne thing I will call out is the network rules. For demonstration purposes I have the source IP set to *. You will want to change this to your IP address, otherwise anyone will be able to connect to your resources.\nVM Let\u0026rsquo;s break down the VM code.\nGiving it a name, rg-terraform\nThis is a reference to our resource groups name\nThis is a reference to our resource groups Azure region\nHere we get to specify the type and size of the VM. I chose a fairly small VM to keep things cheap in our example. You can find all the available types and sizes on Microsoft’s site, or you can use this command to output a list for you right in PowerShell. az vm list-sizes --location \u0026quot;East US 2\u0026quot; --output table\nEnter an admin username and password for your VM. I left a generic set of credentials there for you to use if you want. I would change them if you are doing anything outside of experimenting\nThis is a reference to our network interface card id. The resource was created in our networking.tf file\nHere we configure the cheapest options for our OS disk on the VM\nLast, we specify the operating system and version of SQL Server we want. To get the options I wanted I used the CLI commands to narrow it down. The third option SKU specifies the SQL Server license which can have a big difference in cost, choose wisely.\naz vm image list-skus --location \u0026quot;East US 2\u0026quot; --publisher MicrosoftSQLServer --offer \u0026quot;sql2022-ws2022\u0026quot; --output table\nWrapping Up Deployment of a VM can take a bit longer than the PASS offerings, this is expected. Once Terraform is done deploying the resources they will take a few minutes to finish initializing.\nA note on destroying these resources. I had to run destroy 3 times to remove all of the deployed resources. Seems there is a timeout on removing some resources that have a dependency.\n","permalink":"https://datawrights.com/posts/terraform-azure-sql-server-vm/","summary":"\u003ch2 id=\"intro\"\u003e\u003cstrong\u003eIntro\u003c/strong\u003e\u003c/h2\u003e\n\u003cp\u003eIn this post we are going to deploy a SQL Server VM in Azure. Deploying a VM requires a little more work than the \u003ca href=\"https://dataartisans.tech/terraform-azure-sql-database/\"\u003eSQL Database we deployed in the last post\u003c/a\u003e. We will need to add some networking resources and configure the host VM. If you need help setting up Terraform please see my prior post, \u003ca href=\"http://terraform-azure-setting-up-your-environment\"\u003eTerraform Azure: Setting Up Your Environment\u003c/a\u003e. This post assumes you have an Azure account. If you do not, you can \u003ca href=\"https://azure.microsoft.com/en-us/free/\"\u003ecreate one for free\u003c/a\u003e.\u003c/p\u003e","title":"Terraform Azure: SQL Server VM"},{"content":"Intro In this post we are going to cover how you can use Terraform to create an Azure SQL Database. If you need help setting up Terraform please see my prior post, Terraform Azure: Setting Up Your Environment.This post assumes you have an Azure account. If you do not, you can create one for free.\nWe will take a slow approach to accomplishing our task. The goal here is to get familiar with Terraform and its commands by creating some basic resources. Terraform also has some great resources for getting started here.\nAs you go through the sections of this post you will see screenshots of the code with callouts that I will walk through. You can find all the code for this example on my GitHub repo.\nPrerequisites To create a SQL Database you will need a user to assign admin privileges to. To create a user follow these instructions. If you already have one then you are all set. What we will need from the user is its name and the object id.\nGetting Started Fire up your favorite code editor, in this post I will be using VS Code\nStart a new folder for your project, mine is named sql-db\nCreate new file named main.tf\nThe Provider Up first is the Azure provider. You can find all the docs here. The code below will configure your project to pull the Azure provider and configure it.\nazurerm is the name of the Terraform Azure provider\nWe are using version 3.0 or better\nThis is required to configure the provider\nResource Group Everything in Azure has to belong to a resource group, so that is the first resource we will create.\nOur resource group will be named rg-terraform\nI have set the Azure region for this to East US 2. You can set it to whatever region you prefer.\nServer In order to create a database we have to have a server for it to be a member of. Our server will be named sql-server-terraform\nThis is a reference to our resource groups name\nThis is a reference to our resource groups Azure region\nWe are setting the server to the latest available version\nHere is where we need the name of the admin account we made\nPaste in the object id from the admin account\nAnother item to note here is the azuread_authentication_only property. This is set to true so it will not use SQL Server authentication or mixed mode authentication. To configure mixed mode checkout the example in the Terraform documentation.\nTag the resource with development environment\nDatabase Finally, we have arrived at the database. We will be naming this database db-terraform\nThis is referencing the id of the server we created\nThe most important configurable option here is the sku_name. This is the value the pricing of your database is based on. I have it configured to the cheapest possible option. To get a full list of all the available SKUs you can run this command in powershell az sql db list-editions --location “East US 2” --output table.\nTag the resource with development environment\nAuthenticate You now have all your resources defined and are ready to deploy them to Azure.\nThe first thing we need to do is authenticate to Azure so Terraform can connect.\nOpen a PowerShell terminal in VS Code and run az login. This will open a browser window that asks you to login to your azure account. Initialize Next we need to initialize our Terraform project.\nUse the terraform init command to initialize your project and download all the providers needed\nThis message shows Terraform has initialized successfully\nPlan Now we get to see what Terraform is going to do.\nHere we are running terraform plan to get a listing of the changes Terraform will make to our Azure environment\nThe green + indicates an object will be created\nAnything marked as (known after apply) is usually an id of some kind that Azure will generate after the object is created.\nApply After we have reviewed the plan and decide we like it we can deploy the changes.\nTo deploy our changes we run the terraform apply command\nTerraform will output all of the changes it will make and stop to prompt you to make sure you want to make the changes\nTo confirm the changes enter yes\nThe output will have a listing of Terraform’s progress\nIf everything went well you will have a green success message at the bottom\nValidate To confirm everything worked let\u0026rsquo;s check our Azure account.\nGo to resource groups\nOpen the tg-terraform resource group\nYou should see the server and database resources we defined\nDestroy So we don\u0026rsquo;t land ourselves with a large bill, let\u0026rsquo;s destroy these new resources.\nTo destroy these resources we run the terraform destroy command\nThe red - indicates an object will be destroyed\nTerraform will output all of the changes it will make and stop to prompt you to make sure you want to make the changes\nTo confirm the changes enter yes\nIf everything went well you will have a green success message at the bottom\nTo confirm everything is gone, head back to your Azure account and refresh the page. You should see all of the new resources are now gone.\n","permalink":"https://datawrights.com/posts/terraform-azure-sql-database/","summary":"\u003ch2 id=\"intro\"\u003e\u003cstrong\u003eIntro\u003c/strong\u003e\u003c/h2\u003e\n\u003cp\u003eIn this post we are going to cover how you can use Terraform to create an \u003ca href=\"https://azure.microsoft.com/en-us/products/azure-sql/database/\"\u003eAzure SQL Database\u003c/a\u003e. If you need help setting up Terraform please see my prior post, \u003ca href=\"https://dataartisans.tech/terraform-azure-setting-up-your-environment/\"\u003eTerraform Azure: Setting Up Your Environment\u003c/a\u003e.This post assumes you have an Azure account. If you do not, you can \u003ca href=\"https://azure.microsoft.com/en-us/free/\"\u003ecreate one for free\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eWe will take a slow approach to accomplishing our task. The goal here is to get familiar with Terraform and its commands by creating some basic resources. Terraform also has some great resources for getting started \u003ca href=\"https://developer.hashicorp.com/terraform/tutorials/azure-get-started\"\u003ehere\u003c/a\u003e.\u003c/p\u003e","title":"Terraform Azure: SQL Database"},{"content":"Intro\nYou want to start using Terraform to manage your Azure infrastructure. To get started you will need to get your local development environment setup. In this post I will walk you through setting up Terraform and the Azure CLI on Windows.\nFor a video walkthrough check out my YouTube video.\nPowerShell\nI’m a huge fan of PowerShell so that is my preferred way to interact with Terraform. If you are using Windows you will already have a version of PowerShell available on your machine. I like to use the latest and greatest so I start by installing the latest version which as of this writing is 7.3.1. Download the package and install it, you\u0026rsquo;re done.\nhttps://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows?view=powershell-7.3#msi\nAzure CLI\nIn order for Terraform to interact with Azure you will need to have the Azure CLI installed on your machine. Download the package and install it, you\u0026rsquo;re done.\nhttps://learn.microsoft.com/en-us/cli/azure/install-azure-cli-windows?tabs=azure-cli\nTerraform\nInstalling Terraform is easy but there isn\u0026rsquo;t an installer to do the work for you. Follow these steps.\nDownload the latest version of Terraform, 1.3.7 as of this writing.\nhttps://developer.hashicorp.com/terraform/downloads\nExtract the contents of the zip file and place it in a folder of your choice. I am using C:\\Terraform.\nAdd Terraform to your environment variables. I put Terraform in C:\\Terraform so I will need to add that to the path variable. I won\u0026rsquo;t walk through the steps for doing that here because it has been well documented by others. Below is a written walkthrough and a video walkthrough on how to add a new item to the Path environment variable.\nWritten Steps: https://stackoverflow.com/questions/1618280/where-can-i-set-path-to-make-exe-on-windows\nVideo Walkthrough: https://www.youtube.com/watch?v=ow2jROvxyH4\nFinishing Up\nTo ensure everything recognizes all the new packages and new configuration, reboot your machine. Once Windows has rebooted we will check the versions of all software we just installed.\nCheck PowerShell version\n$PSVersionTable.PSVersion\nCheck Azure CLI version\naz –-version\nCheck Terraform version\nterraform –version\n","permalink":"https://datawrights.com/posts/terraform-azure-setting-up-your-environment/","summary":"\u003cp\u003e\u003cstrong\u003eIntro\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eYou want to start using Terraform to manage your Azure infrastructure. To get started you will need to get your local development environment setup. In this post I will walk you through setting up Terraform and the Azure CLI on Windows.\u003c/p\u003e\n\u003cp\u003eFor a video walkthrough check out my \u003ca href=\"https://www.youtube.com/watch?v=HFyi0ZnmAho\"\u003eYouTube video\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003ePowerShell\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eI’m a huge fan of PowerShell so that is my preferred way to interact with Terraform. If you are using Windows you will already have a version of PowerShell available on your machine. I like to use the latest and greatest so I start by installing the latest version which as of this writing is 7.3.1. Download the package and install it, you\u0026rsquo;re done.\u003c/p\u003e","title":"Terraform Azure: Setting Up Your Environment"},{"content":"Intro\nIn our previous post we discussed the difference between the AthenaHealth data delivery options. In this post we are going to cover how to connect Power BI to Data View. This post assumes you have already installed Power BI on your computer. If you have not you can download it here.\nGather Information\nTo get started you will need to find out what your SnowFlake URL is. In Athena if you open Practice Manager Admin there is an option for Data View Settings. To access this your Athena account will need to be in the Data View Admin role. Once on the Data View Setting page you should see your URL at the top of the page. Copy that URL somewhere so we can use it later.\nConnect\nOpen up Power BI and click Get Data then More….\nOn the next screen type snow into the search box, select Snowflake, and click Connect.\nNow you will need that URL we copied from Athena earlier. Paste in everything from your URL after the https:// into the Server field. In the Warehouse field enter AH_WAREHOUSE, and in the Database field enter ATHENAHEALTH. Click OK to connect.\nOnce connected you will see the ATHENAHEALTH database, click the carrot to expand it. Underneath you will see all of the schemas. Expanding any one of those will expose the tables available. From there you can select which tables you want to bring into your report\\data model.\n","permalink":"https://datawrights.com/posts/athenahealth-connect-power-bi-to-data-view/","summary":"\u003cp\u003e\u003cstrong\u003eIntro\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eIn our \u003ca href=\"https://dataartisans.tech/athenahealth-data-view-vs-data-warehouse-feed/\"\u003eprevious post\u003c/a\u003e we discussed the difference between the \u003ca href=\"https://www.athenahealth.com/\"\u003eAthenaHealth\u003c/a\u003e data delivery options. In this post we are going to cover how to connect Power BI to Data View. This post assumes you have already installed Power BI on your computer. If you have not you can download it \u003ca href=\"https://powerbi.microsoft.com/en-us/downloads/\"\u003ehere\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eGather Information\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eTo get started you will need to find out what your \u003ca href=\"https://docs.snowflake.com/en/user-guide/connecting.html\"\u003eSnowFlake URL\u003c/a\u003e is. In Athena if you open Practice Manager Admin there is an option for Data View Settings. To access this your Athena account will need to be in the Data View Admin role. Once on the Data View Setting page you should see your URL at the top of the page. Copy that URL somewhere so we can use it later.\u003c/p\u003e","title":"AthenaHealth: Connect Power BI to Data View"},{"content":"Intro\nAthenahealth offers two options for receiving data from their EMR. They offer either the Data Warehouse Feed or Data View. This post will describe each option and the difference between the two.\nData Warehouse Feed\nThe data warehouse feed is athena’s traditional data offering. It has been around for a quite some time and functions like most traditional data feeds. Data is delivered on a daily basis in flat files to an FTP site. When first setting up this option Athena will send a larger set of files for your initial load. These files contain all of your data back to when you implemented Athena. Depending on the size of your business, these files can be very large and difficult to process if you don\u0026rsquo;t have the proper tools. Everyday after you will receive daily update files. The daily update files contain data that has been added or changed since the prior data delivery. Most of the time these files are very small in size, but sometimes Athena will update most of the records in your dataset so these can randomly be the same size as your initial load files.\nNow that you have the data in flat files it is up to you to load them into a system you can report from. For smaller clients it is definitely possible to use a reporting tool directly on top of the flat files, but this is an uncommon scenario. From what I have seen most folks will load these files into a relational database and layer their reporting tool on that.\nData View\nAthena launched their new data product in the last few years named Data View. This new product takes a modern approach to data delivery. Using the Snowflake data platform they are able to provide a functioning database for clients to use.\nThis product is updated on a daily basis as well. Daily updates are done by athena and are available to you automatically. The number of rows updated daily can vary. Generally it is a manageable update, but occasionally the majority of the data can get updated.\nSnowflake offers a web interface clients can use to query and export data right in their favorite web browser. With snowflake’s explosion in popularity you can also connect most reporting\\etl tools directly to the database. Snowflake also offers an ODBC driver you can download. As an initial step I have seen many folks use the ODBC driver to setup Data View as a linked server on their existing SQL Server.\nYou can read more on the Athena developer page.\nComparison\nProduct Updates\nThe Data View dataset started out the same as the Data Warehouse Feed. In the last 2 years athena has invested in expanding the dataset significantly. Data View usually receives an update once a month. These updates add new tables and add columns to existing tables. Some updates have included access to queries behind athena built reports. In comparison the Data Warehouse Feed is static. It does not change unless you go through an upgrade project. Majority of development efforts have shifted to Data View so you will not see significant changes to the flat files anytime soon.\nWith automatic monthly updates to Data View there is no effort on the client side to stay on the latest version. The Data Warehouse Feed requires a project and planned upgrade to get onto the latest release. Monthly updates that you don\u0026rsquo;t have to put in an effort for vs an upgrade project every couple years is a win in my book.\nData Delivery\nHaving data delivered via flat files vs a cloud database is really a simple comparison from my point of view. With the Data Warehouse Feed flat files, the client is responsible for the hardware\\software necessary to take advantage of these files. If you have obsolete hardware and dated software you are going to have a bad time here. On top of that you also need someone with the skillset to make all that function. The ready to query database Data View provides is fast, reliable, and online from day 1 of implementation.\nTiming\nThis is one area the Data Warehouse Feed comes out on top. The files are generally available early in the morning where Data View has an SLA of 8AM EST. In my experience the Data View data is generally available well before 8 but it is still a couple hours behind the Data Warehouse Feed. If daily operational reporting is critical for you this might be something to consider.\nConclusion\nathenahealth provides two great options for accessing your data. Either option grants you access to a robust dataset that is useful for gaining insights. Data View is definitely the best way to move forward with accessing this data. It is an excellent product that athena is clearly invested in improving. Data View provides a fast and reliable way to access your data with minimal time investment required.\n","permalink":"https://datawrights.com/posts/athenahealth-data-view-vs-data-warehouse-feed/","summary":"\u003cp\u003e\u003cstrong\u003eIntro\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://www.athenahealth.com/\"\u003eAthenahealth\u003c/a\u003e offers two options for receiving data from their EMR. They offer either the Data Warehouse Feed or Data View. This post will describe each option and the difference between the two.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eData Warehouse Feed\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eThe data warehouse feed is athena’s traditional data offering. It has been around for a quite some time and functions like most traditional data feeds. Data is delivered on a daily basis in flat files to an FTP site. \u003c/p\u003e","title":"AthenaHealth Data View vs Data Warehouse Feed"},{"content":"Intro\nIn some scenarios a vendor or other 3rd party will send you a copy of their log shipping backups so you can keep a reporting copy of their database. Today\u0026rsquo;s post will cover how we can use dbatools to automate the restore process. This post assumes you have already restored the initial full backup and are now at the point where you are ready to automate the transaction log backups you are receiving.\nGather Information\nWe only need to know a few things to get this script up and running.\nSQL Server Instance Name Database Name Transaction Log Backup File Path Standby File Path The Script\nIn our development scenario we are going to script the restore of database db_dev on the default instance of SQL Server. To do this we will use the Restore-DbaDatabase command. This script will go through all files and folders within the $BackupPath provided and restore them. All you need to do to take advantage of this is swap out the variable values with your own.\n$Instance = \u0026#39;.\u0026#39; $Database = \u0026#39;db_dev\u0026#39; $BackupPath = \u0026#39;F:\\backup_stage\u0026#39; $StandbyPath = \u0026#39;F:\\standby\u0026#39; try { Restore-DbaDatabase -SqlInstance $Instance -DatabaseName $Database -Path $BackupPath -Continue -StandbyDirectory $StandbyPath -DirectoryRecurse } catch { \u0026#34;Error occurred restoring DB\u0026#34; } Logging\nSometimes unforeseen events occur and cause issues. Capturing logs with your script can make troubleshooting much easier when this happens. I like to use the Start-Transcript command because it is easy to implement and outputs everything the script is doing. Below is an updated version of our script to output logs. It will output a new log file every time it runs.\n$FileLog = \u0026#34;F:\\script_logs\\Restore_\u0026#34; + (Get-Date).ToString(\u0026#34;yyyyMMddHHmmss\u0026#34;) + \u0026#34;.log\u0026#34; Start-Transcript -Path $FileLog $Instance = \u0026#39;.\u0026#39; $Database = \u0026#39;db_dev\u0026#39; $BackupPath = \u0026#39;F:\\backup_stage\u0026#39; $StandbyPath = \u0026#39;F:\\standby\u0026#39; try { Restore-DbaDatabase -SqlInstance $Instance -DatabaseName $Database -Path $BackupPath -Continue -StandbyDirectory $StandbyPath -DirectoryRecurse } catch { \u0026#34;Error occurred restoring DB\u0026#34; } Stop-Transcript Conclusion\nWe covered how to automate the restore process of log files with dbatools. This will leave the database in standby mode so it is ready for the next set of files. We also covered how to implement a basic logging solution so you have some information to work from if issues occur.\n","permalink":"https://datawrights.com/posts/log-shipping-restore-with-dbatools/","summary":"\u003cp\u003e\u003cstrong\u003eIntro\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eIn some scenarios a vendor or other 3rd party will send you a copy of their \u003ca href=\"https://docs.microsoft.com/en-us/sql/database-engine/log-shipping/about-log-shipping-sql-server\"\u003elog shipping\u003c/a\u003e backups so you can keep a reporting copy of their database. Today\u0026rsquo;s post will cover how we can use \u003ca href=\"https://dbatools.io/\"\u003edbatools\u003c/a\u003e to automate the restore process. This post assumes you have already restored the initial full backup and are now at the point where you are ready to automate the transaction log backups you are receiving.\u003c/p\u003e","title":"Log Shipping Restore With dbatools"},{"content":"Intro\nIn this post I will describe how to manage the state of a VM with Azure Data Factory (ADF). I was inspired to write this post after reading a very similar walk through on Tech Talk Corner. A VM can be in one of several states, for this post we are going to focus on Running and Deallocated. When a VM is running you are being billed for it and able to access its resources. If the VM is deallocated you are not being billed for it and its resources are inaccessible. In many scenarios it makes sense to have a VM in a deallocated state to save on cost and only keep it running when absolutely necessary.\nGather Information\nTo make this solution work we will need a few pieces of information from the VM. All of this information can be found on the Overview page of the VM in the Azure portal.\nSubscription ID Resource Group Region VM Name Grant Permission\nAfter gathering all of the information above from the Overview page navigate to the Access control (IAM) page. Here you will need to add your ADF managed identity to the Virtual Machine Contributor role.\nManagement Pipeline\nThere are several ways to implement this in ADF. I found the best way for me was to create a new pipeline that I can call with either the Start or Stop command. In this pipeline we will create a web activity that uses the Azure Compute REST API.\nCreate a new pipeline. I named mine VM_StartStop for easy reference. Name yours whatever you would like. Create 5 parameters leaving the type set to String. Set all of the parameters except Command default value to the values gathered earlier. SubscriptionId ResourceGroupName Region VmName Command Create a new Web activity. In the Web activity settings update the following URL = @concat(\u0026rsquo;https://management.azure.com/subscriptions/\u0026rsquo;,pipeline().parameters.SubscriptionId,\u0026rsquo;/resourceGroups/\u0026rsquo;,pipeline().parameters.ResourceGroupName,\u0026rsquo;/providers/Microsoft.Compute/virtualMachines/\u0026rsquo;,pipeline().parameters.VmName,\u0026rsquo;/\u0026rsquo;,pipeline().parameters.Command,\u0026rsquo;?api-version=2021-11-01') Method = POST Body = @concat(\u0026rsquo;{\u0026rsquo;,\u0026rsquo;}') Authentication = System Assigned Managed Identity Resource = https://management.azure.com/ Integrating\nNow that the management pipeline has been created we can call it from anywhere within our Data Factory. All you have to do is add an Execute Pipeline activity and pass either Start or Deallocate in the Command parameter.\nConclusion\nWe covered how to implement a VM management pipeline that can be called from any other pipeline to turn a VM on and off. The pattern I used was to call the management pipeline to start the VM, do the work I needed to do with the VM resources, then deallocate the VM. Using this pattern I am able to minimize cost for VM resources, especially those using expensive licensing like SQL Server Enterprise. For further reading I strongly recommend checking out the post on Tech Talk Corner which also covers how to check the status of the VM.\n","permalink":"https://datawrights.com/posts/start-and-stop-vm-with-azure-data-factory/","summary":"\u003cp\u003e\u003cstrong\u003eIntro\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eIn this post I will describe how to manage the state of a VM with Azure Data Factory (ADF). I was inspired to write this post after reading a very similar walk through on \u003ca href=\"https://www.techtalkcorner.com/start-and-stop-azure-vm/\"\u003eTech Talk Corner\u003c/a\u003e. \u003c/p\u003e\n\u003cp\u003eA VM can be in one of \u003ca href=\"https://docs.microsoft.com/en-us/azure/virtual-machines/states-billing\"\u003eseveral states\u003c/a\u003e, for this post we are going to focus on Running and Deallocated. When a VM is running you are being billed for it and able to access its resources. If the VM is deallocated you are not being billed for it and its resources are inaccessible. In many scenarios it makes sense to have a VM in a deallocated state to save on cost and only keep it running when absolutely necessary.\u003c/p\u003e","title":"Start and Stop VM with Azure Data Factory"},{"content":"Intro\nSQL Server Management Studio (SSMS) is a great product. Out of the box SSMS is an awesome tool that many of us have come to know and love. In my quest for efficiency I have found some very helpful settings that can be changed. If you spend most of your day in SSMS like I do, these changes can help you be more productive.\nVersion\nFirst and foremost is the version you are running. If you aren\u0026rsquo;t running the latest version of SSMS go download it now. It\u0026rsquo;s free! SSMS has received a lot of love from Microsoft over the last couple years. Now updates come out regularly instead of with the SQL Server release cycle. If you are still running SSMS 2005 I’m begging you to go download the latest version and give it a try.\nLine Numbers\nNext up is line numbers. A basic necessity for any code editor. Now when SSMS tells you there is an error on line 2746 you can actually find it! Sharing code with a colleague becomes easier because you can reference specific lines.\nTools → Options → Text Editor → Transact-SQL → Line Numbers\nClean Tabs\nTab names are way too crowded. We can remove a lot of the repetitive information to make the tab names easier to read and mentally organize.\nTools → Options → Text Editor → Editor Tab and Status Bar → Tab Text\nTwo Rows of Tabs\nHaving a million tabs open can be painful to sort through. You can double up your tab real estate by enabling pinned tabs in a separate row. Instantly makes SSMS easier to multitask with.\nTools → Options → Environment → Tabs and Windows → Show pinned tabs in a separate window\nSQL Search\nTo make anything in SQL Server easier to find I use SQL Search. It\u0026rsquo;s a free add-in for SSMS provided by Red Gate. The free download and documentation can be found at the link below. SQL Search will search through every object in SQL Server for the search term you enter.\nSQL Prompt\nSQL Prompt is the only paid tool in my arsenal. This tool is also made by Red Gate. The value it brings easily justifies the cost. There are so many features, my favorite 3 are Tab History, Object Inspection and Code Formatting.\nTab history is such a life saver. If you have ever accidentally closed a tab without saving or had your PC shutdown before saving, you know where I am coming from with this. You can quickly and easily access all your recent tabs whether you saved them or not.\nHaving object inspection is really handy. It takes intellisense to the next level. When you\u0026rsquo;re typing out a statement that refers to an object it will provide a list of available objects that match what you have typed so far. On top of that you can hover over the suggested objects and see their definition. For example you could see a table’s columns and their data types. It will even give you the create script.\nLast but not least is code formatting. With the click of a button you can take a horribly formatted T-SQL statement and have it format it in seconds. You can even customize the style for its formatting. The time saved in properly formatting a statement is priceless.\nConclusion\nThis is how I configure SSMS for my day to day work. I hope you find some of these settings useful. Let me know in the comments which ones you liked the best!\n","permalink":"https://datawrights.com/posts/how-to-configure-sql-server-management-studio-for-efficiency/","summary":"\u003cp\u003e\u003cstrong\u003eIntro\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eSQL Server Management Studio (SSMS) is a great product. Out of the box SSMS is an awesome tool that many of us have come to know and love. In my quest for efficiency I have found some very helpful settings that can be changed. If you spend most of your day in SSMS like I do, these changes can help you be more productive.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eVersion\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eFirst and foremost is the version you are running. If you aren\u0026rsquo;t running the latest version of SSMS go \u003ca href=\"https://docs.microsoft.com/en-us/sql/ssms/download-sql-server-management-studio-ssms\"\u003edownload\u003c/a\u003e it now. It\u0026rsquo;s free! SSMS has received a lot of love from Microsoft over the last couple years. Now updates come out regularly instead of with the SQL Server release cycle. If you are still running SSMS 2005 I’m begging you to go download the latest version and give it a try.\u003c/p\u003e","title":"How to Configure SQL Server Management Studio for Efficiency"},{"content":"I had some issues installing dbatools over the weekend and wanted to share my experience. If you have not heard of dbatools I encourage you to go check it out and see what it can do.\nThe easiest method to install dbatools is to open PowerShell as administrator and run the following command:\nInstall-Module dbatools Following the install instructions on the dbatools website and other relevant blog posts around the web the install should be as easy as that. In my case it was not.\nAfter I ran the command it prompted me to install a NuGet provider. When installing the NuGet provider I encountered the error:\nWARNING: Unable to download from URI \u0026#39;https://go.microsoft.com/fwlink/?LinkID=627338\u0026amp;clcid=0x409\u0026#39; to \u0026#39;\u0026#39;. WARNING: Unable to download the list of available providers. Check your internet connection. To resolve this issue I had to set my PowerShell session to use TLS 1.2.\n[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 Once I did this I was able to continue installing dbatools and encountered no other errors.\n","permalink":"https://datawrights.com/posts/installing-dbatools/","summary":"\u003cp\u003eI had some issues installing \u003ca href=\"https://dbatools.io/\"\u003edbatools\u003c/a\u003e over the weekend and wanted to share my experience. If you have not heard of dbatools I encourage you to go check it out and see what it can do.\u003c/p\u003e\n\u003cp\u003eThe easiest method to install dbatools is to open PowerShell as administrator and run the following command:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-powershell\" data-lang=\"powershell\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eInstall-Module dbatools\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eFollowing the \u003ca href=\"https://dbatools.io/download/\"\u003einstall instructions on the dbatools website\u003c/a\u003e and other relevant blog posts around the web the install should be as easy as that. In my case it was not.\u003c/p\u003e","title":"Installing dbatools"},{"content":"You are handed a SQL Server that someone else set up and has, or more likely has not, maintained over time. You are now responsible for this server, but have limited time to check it out because of your busy schedule. What are your first 3 SQL Server settings to check?\n1. Backups This should always without a doubt be the first thing you check. If backups are failing or even are non existent, you need to know about it and make it your first priority to fix. Now that this server is your responsibility, the business is going to look at you when the server crashes and they need a restore. Not being able to recover any data is a great way to get fired!\nHere is a script you can use to check the backups on your server. When you run this and don’t see any dates, or the dates are from 3 years ago you have a problem. Current dates are a good sign that your backups are succeeding. Even if the dates are current you should still investigate further to understand the backup solution that is in place and how it is meeting your RPO and RTO goals.\nSELECT SDB.[name] AS \u0026#39;DatabaseName\u0026#39;, COALESCE(CONVERT(char(10), MAX(BUS.backup_finish_date), 101),\u0026#39;!Never!\u0026#39;) AS \u0026#39;LastBackUpTime\u0026#39; FROM sys.sysdatabases AS SDB LEFT OUTER JOIN msdb.dbo.backupset AS BUS ON BUS.[database_name] = SDB.[name] WHERE SDB.[name] \u0026lt;\u0026gt; \u0026#39;tempdb\u0026#39; GROUP BY SDB.[name] ORDER BY SDB.[name] If you find the server doesn’t have any backups it\u0026rsquo;s time to put some in place. So where do you start? Redgate has a great article on backups if you aren’t familiar with the basics. For a backup solution Ola Hallengren has got you covered with his ever popular maintenance solution that is free!\n2. Corruption Checks 9 times out of 10 when I check out a new server, corruption checks are not being done. Last known good corruption check is never. If there is corruption on this new server you want to find out about it right away so you can do 2 things. First, you can make everyone aware of the issue, so nobody can blame you for it. If you let it sit for 6 months and then find out the database is corrupted, everyone will have forgotten about that last guy that maintained this server and blame you. Second, you start working on the issue before it gets any worse.\nUse the DBCC command below to see when the last corruption check was on your database. Look for the record with value dbi_dbccLastKnownGood in the field column. It will have the date of the last corruption check. If the date is 1900/01/01 then your database has never been checked for corruption.\nDBCC DBINFO(\u0026#39;YourDatabaseName\u0026#39;) WITH TABLERESULTS My favorite resources for learning about corruption are Steve Stedman’s site and SQLskills. If you don\u0026rsquo;t know anything about corruption, they have some great resources to get you started. To start checking for corruption regularly Ola Hallengren has our back again with integrity checks being a part of his free maintenance solution.\n3. Security Knowing the landscape for security on a server is huge. Time and time again, I see servers where everyone has sys admin privileges. If other people have full control over the server you are responsible for, you need to know about it and make others aware of it. Remember you have no way to prevent these people from doing something stupid! With this you also run the risk of their accounts being compromised because they surf the web and open phishing emails with these accounts everyday. It\u0026rsquo;s only a matter of time before something bad happens! When you put your money in the bank you expect them to tightly control who has access to it right? Your employer expects no less of you with their data! Protecting your users from themselves can be an uphill battle but it is worth it in the end.\nCheck out this article on SQL Server access control to get some basic information on SQL Server security. You can use this script to identify the accounts and/or groups that have sys admin privledges on your SQL Server.\nexec sp_helpsrvrolemember \u0026#39;sysadmin\u0026#39; ","permalink":"https://datawrights.com/posts/first-3-sql-server-settings-to-check/","summary":"\u003cp\u003eYou are handed a SQL Server that someone else set up and has, or more likely has not, maintained over time. You are now responsible for this server, but have limited time to check it out because of your busy schedule. What are your first 3 SQL Server settings to check?\u003c/p\u003e\n\u003ch4 id=\"1-backups\"\u003e1. \u003cstrong\u003eBackups\u003c/strong\u003e\u003c/h4\u003e\n\u003cp\u003eThis should always without a doubt be the first thing you check. If backups are failing or even are non existent, you need to know about it and make it your first priority to fix. Now that this server is your responsibility, the business is going to look at you when the server crashes and they need a restore. Not being able to recover any data is a great way to get fired!\u003c/p\u003e","title":"First 3 SQL Server Settings to Check"},{"content":"Ever wish your data was a little different so it is easier to query? Don\u0026rsquo;t fret, we have all had those queries that are gigantic and become too cumbersome to read through or modify. A CTE, a.k.a. Common Table Expression, can be the savior you have been wishing for. They are great for separating different pieces of your query and performing some tasks before your query runs.\nTo use a CTE:\n1. Use a WITH clause. 2. Add a name for the CTE followed by AS. 3. Within parentheses, put in the query you want to run before your main query.\nSounds easy, right? I am not pulling the wool over your eyes here. It is that easy. Let’s break it down with a simple example.\nExample Objective\nOutput total charges for each patient.\nTables\n1. Visit 2. Charge Steps\n1. Build CTE Reshape the charge data to the format that is easiest to query. SUM the amount column and group by VisitId to return total charge by visit.\nWITH Charges AS ( SELECT VisitId, SUM(Amount) AS \u0026#39;Charges\u0026#39; FROM dbo.Charge GROUP BY VisitId ) With this we have successfully transformed the charge table: 2. Build Main Query Join the Visit table to Charges to get the total charges for each patient.\nSELECT VIS.VisitId, CHG.Charges FROM dbo.Visit AS VIS JOIN Charges AS CHG ON VIS.VisitId = CHG.VisitId 3. Execute Script\nWITH Charges AS ( SELECT VisitId, SUM(Amount) AS \u0026#39;Charges\u0026#39; FROM dbo.Charge GROUP BY VisitId ) SELECT VIS.VisitId, CHG.Charges FROM dbo.Visit AS VIS JOIN Charges AS CHG ON VIS.VisitId = CHG.VisitId Just when you think it can\u0026rsquo;t get any better it does!\nWe can take this a step further and use more than one CTE in a query. In the next example we will use two to solve a different type of problem.\nExample Objective\nOutput current price and CPT code for each charge in the charge dictionary.\nTables\n1. ChargeDictionary 2. ChargePrice 3. ChargeCode Steps\n1. Build PriceDate CTE Reshape the ChargePrice table to output the latest EffectiveDate. Notice the comma at the end of this one. That is how we tell SQL Server we want more than one CTE.\nWITH PriceDate AS ( SELECT ChargeProcedure, MAX(EffectiveDate) AS \u0026#39;EffectiveDate\u0026#39; FROM dbo.ChargePrice GROUP BY ChargeProcedure ), 2. Build CodeDate CTE Reshape the ChargeCode table to output the latest EffectiveDate.\nCodeDate AS ( SELECT ChargeProcedure, MAX(EffectiveDate) AS \u0026#39;EffectiveDate\u0026#39; FROM dbo.ChargeCode GROUP BY ChargeProcedure ) 3. Build Main Query Join the PriceDate and CodeDate along with the ChargePrice and ChargeCode tables to get only the latest price and code for each charge.\nSELECT CD.ChargeProcedure, CP.Price, CC.Code FROM dbo.ChargeDictionary AS CD JOIN PriceDate AS P ON P.ChargeProcedure = CD.ChargeProcedure JOIN dbo.ChargePrice AS CP ON CD.ChargeProcedure = CP.ChargeProcedure AND CP.EffectiveDate = P.EffectiveDate JOIN CodeDate AS C ON C.ChargeProcedure = CD.ChargeProcedure JOIN dbo.ChargeCode AS CC ON CD.ChargeProcedure = CC.ChargeProcedure AND CC.EffectiveDate = C.EffectiveDate 4. Execute Script\nWITH PriceDate AS ( SELECT ChargeProcedure, MAX(EffectiveDate) AS \u0026#39;EffectiveDate\u0026#39; FROM dbo.ChargePrice GROUP BY ChargeProcedure ), CodeDate AS ( SELECT ChargeProcedure, MAX(EffectiveDate) AS \u0026#39;EffectiveDate\u0026#39; FROM dbo.ChargeCode GROUP BY ChargeProcedure ) SELECT CD.ChargeProcedure, CP.Price, CC.Code FROM dbo.ChargeDictionary AS CD JOIN PriceDate AS P ON P.ChargeProcedure = CD.ChargeProcedure JOIN dbo.ChargePrice AS CP ON CD.ChargeProcedure = CP.ChargeProcedure AND CP.EffectiveDate = P.EffectiveDate JOIN CodeDate AS C ON C.ChargeProcedure = CD.ChargeProcedure JOIN dbo.ChargeCode AS CC ON CD.ChargeProcedure = CC.ChargeProcedure AND CC.EffectiveDate = C.EffectiveDate I hope these two examples have helped you understand how to make your data easier to query. For more reading on this topic check out the articles listed below. Let me know in the comments how you used a CTE and how it helped solve a problem.\nAdditional Resources redgate Microsoft StackOverflow\n","permalink":"https://datawrights.com/posts/cte-how-to-make-your-data-easier-to-query/","summary":"\u003cp\u003eEver wish your data was a little different so it is easier to query? Don\u0026rsquo;t fret, we have all had those queries that are gigantic and become too cumbersome to read through or modify. A CTE, a.k.a. Common Table Expression, can be the savior you have been wishing for. They are great for separating different pieces of your query and performing some tasks before your query runs.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eTo use a CTE:\u003c/strong\u003e\u003c/p\u003e","title":"CTE: Make Your Data Easier to Query"},{"content":"Once upon a time a vendor set up a new SQL Server at the company I was working for. For whatever reason they decided it best to not work with the local DBA. A few weeks later a server admin emails me asking if I can help out with an issue they were having. He says the vendor has lost the sa password and cannot connect to the SQL Server instance. After having a good chuckle I agreed to help out and reset the SQL Server sa password. Here is how I did it:\nFirst things first. You need to be logged in to the server with an account that is a member of the local administrators group on the server. Without that all that follows will not work for you. You also need to be able to stop the SQL Server service. This means the database(s) will be offline for a period of time. Do not do this on a production server unless you have scheduled down time.\nWith that said the first thing we need to do is stop the SQL Server service. You can do this several different ways. The easiest method is using the SQL Server Configuration Manager. Open it up, right click the SQL Server service, and click Stop.\nNow that the service has stopped we need to add the -m startup parameter to the service. This will force SQL Server to start in single-user mode the next time it starts. We want it in single-user mode because this grants anyone in the local administrators group on the server sysadmin privileges. To add the new startup parameter right click on the SQL Server service and click properties. Then click the Startup Parameters tab, type -m in the Specify a startup parameter text box, click add, and then OK.\nOnce you click Apply a pop up box will come up telling you that you have to restart the service for the change to take effect. Click OK to close the pop up. Now right click the SQL Server service and click start.\nNow that our SQL Server instance is up and running in single-user mode, we need to connect to it and modify permissions. To connect to the instance start an elevated command prompt. Once in command prompt type sqlcmd and hit enter.\nFinally we are at the point where we can reset the sa password. In this example I chose to reset the password to 12345. I suggest you reset yours to something much more complex. Simply type in ALTER LOGIN sa WITH PASSWORD = \u0026lsquo;12345’, hit enter, type in GO, and hit enter one last time.\nWith the sa password reset you can now login to the SQL instance and get what you need done. Make sure to remove the single-user mode parameter and restart the instance. Or that could be a fun problem for one of your coworkers to try and figure out\u0026hellip;\n","permalink":"https://datawrights.com/posts/how-to-reset-sql-server-sa-password/","summary":"\u003cp\u003eOnce upon a time a vendor set up a new SQL Server at the company I was working for. For whatever reason they decided it best to not work with the local DBA. A few weeks later a server admin emails me asking if I can help out with an issue they were having. He says the vendor has lost the sa password and cannot connect to the SQL Server instance. After having a good chuckle I agreed to help out and reset the SQL Server sa password. Here is how I did it:\u003c/p\u003e","title":"Reset SQL Server sa Password"},{"content":"I have been back and forth with the idea of blogging for a long time now. I read other people’s blogs daily and I really enjoy them. Constantly I get ideas that I would like to see blogged about, especially from bloggers I currently read. Time and time again I have written down my ideas for blog posts, maybe even managed to get a few paragraphs typed out. Nothing ever came of them besides consuming disk space on my laptop. So here it is, I finally made my first blog post. What was different this time than the other times? 3 things come to mind when I ask myself that question.\nThe first and foremost is Brent Ozar and company. If you are not familiar with their work and you’re a data professional you should really check them out https://www.brentozar.com/. It is absolutely amazing and different than anything else you will read, and that is precisely why I can’t get enough of it. The style is unlike any other and keeps me coming back. Brent also keeps a personal blog outside of the company blog https://ozar.me/. Here he blogs about other related topics that are great. For instance one post about his office setup. This is the kind of thing that I love to see and don’t see enough of. Brent has been a huge inspiration behind how and what I want to blog about.\nSecond is Andy Leonard. I read his stuff regularly, and one day while I was again thinking about blogging I come across this post. How can I ignore that? He calls out most of the problems with blogging that have come to mind. After reading his post I felt challenged to finally write down my first post and get it out there to see where it goes.\nLast but not least is my desire to teach and do things differently. While I enjoy reading others blog posts I wish there were more like Brent’s. Something different and on off, but related topics. I am not sure if anyone else wants more content like that but I sure do. So it is my goal to be different than other blogs of data professionals. I am not sure what will come of it at this point but I am glad to start the journey and share with everyone.\n","permalink":"https://datawrights.com/posts/my-first-blog-post/","summary":"\u003cp\u003eI have been back and forth with the idea of blogging for a long time now. I read other people’s blogs daily and I really enjoy them. Constantly I get ideas that I would like to see blogged about, especially from bloggers I currently read. Time and time again I have written down my ideas for blog posts, maybe even managed to get a few paragraphs typed out. Nothing ever came of them besides consuming disk space on my laptop. So here it is, I finally made my first blog post. What was different this time than the other times? 3 things come to mind when I ask myself that question.\u003c/p\u003e","title":"My First Blog Post"}]