handling mysql transaction mysql, the beego way

Lets use the beegos transaction method to do transactional queries in mysql

package main

import (
    _ "github.com/go-sql-driver/mysql"

func init() {
    orm.RegisterDriver("mysql", orm.DR_MySQL)
    orm.RegisterDataBase("default", "mysql", "root:@/mts_dev?charset=utf8")

func main() {
    o := orm.NewOrm()

    var error_list []interface{}

    err := o.Begin()
    if err != nil {
        error_list = append(error_list, err)
    for i := 0; i < 5; i++ {
        if val, err := o.Raw("INSERT into tickets set locked_by = ? ,booked_by = ?", i, i*i).Exec(); err == nil {
            fmt.Println("inserted", i, (i * i), "ID", val)
        } else {
            error_list = append(error_list, err)
            fmt.Println("Error in insert", err)

    if len(error_list) != 0 {
        fmt.Println("Rollback", len(error_list), "Errors", error_list)
        err = o.Rollback()
    } else {
        err = o.Commit()

To know how to bootstrap the initial part of code, please see previous post.

Let us run through each line of code

    var error_list []interface{}

    err := o.Begin()
    if err != nil {
        error_list = append(error_list, err)

We initiate a list variable that will hold all the error messages.

We BEGIN the transaction using o.Begin()

And we append the error to the list if there is any error executing the query.

    for i := 0; i < 5; i++ {
        if val, err := o.Raw("INSERT into tickets set locked_by = ? ,booked_by = ?", i, i*i).Exec(); err == nil
            fmt.Println("inserted", i, (i * i), "ID", val)
        } else {
            error_list = append(error_list, err)
            fmt.Println("Error in insert", err)

We loop and do insert. Catch if any error occurs and append it to the list variable error_list.

    if len(error_list) != 0 {
        fmt.Println("Rollback", len(error_list), "Errors", error_list)
        err = o.Rollback()
    } else {
        err = o.Commit()

If there is no errors in the error_list, if the error_list length is 0




  1. Try making the insert query worng by adding a typo in the column name, and see the results.
  2. Instead of looping, write 5 distinct insert queries, and make the 5th query fail, and see if the 4 other queries are rolled back or not.

Find the source code here

Handling a mysql Transaction BEGIN / COMMIT / ROLLBACK with beego and GO, using raw sql

There is a way Beego handles transaction. I will post a blog on it later. This round is to give an idea about how error and BEGIN/COMMIT work with beego and GO language.

This exercise requires you to have this table schema in your test database

CREATE TABLE `tickets` (
  `locked_by` int(11) DEFAULT NULL,
  `booked_by` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)

Load up a row to have our tests run

INSERT INTO tickets values();

Lets get your code Boostraped.

Get it from here: https://gist.github.com/sumitasok/bfaa8a7194d3532878e9#file-bootstrap_beego_orm-go

Use this code to start the exercise.

Update the below line of code in bootstrap file with your mysql settings

orm.RegisterDataBase("default", "mysql", "mysql_username:mysql_password@/database_name?charset=utf8")

A Transaction in mysql start with BEGIN, finishes with COMMIT on complete success, or executes ROLLBACK on failure at any point.


QUERY X: UPDATE a value in a table.row

QUERY Y: tries UPDATE a value in a table and fails



When Query Y fails, the changes done by Query X should be reverted. That’s the whole point about a transaction rollback.

Every o.Raw(“Query”).Exec() returns two results, One is the result itself and the next is the err_status. If the second retur value is not nil, it means the query failed.

o here is a newORM instance. refer the bootstrap file. Line

    o := orm.NewOrm()

So lets write a raw query that prints the error message when it fails.

Right below the above lines in bootstrap file, add

    if _, err1 := o.Raw("UPDATE tickets set booked_by = 12345 where id = 1").Exec(); err1 != nil {
        fmt.Println("Error 1", err1)
    } else {

Please remember to reset the values of all columns to 0 in row with id as 1. Every single time we run the code

This is a passing line of code. So the output will be “Perfect!” and the data change will be seen in mysql database row.

Lets change the value 12345 to a string, “12345_string”. booked_by is an integer column, and trying to assign a string vaue to it will through error. Lets do that.

Now the code will look like below,

    if _, err1 := o.Raw("UPDATE tickets set booked_by = '12345_string' where id = 1").Exec(); err1 != nil {
        fmt.Println("Error 1", err1)
    } else {

Run the file with go run command

Output will be: Error 1 Error 1265: Data truncated for column ‘booked_by’ at row 1

We just saw how the error catchiing works with o.Raw().Exec() command.

Now lets see how we can use this to get the transaction feature of mysql.

BEGIN is the raw sql query that starts a transaction Lets send it through the ORM.

Replace the above example with this code now, in the boot strap file.


    if _, err1 := o.Raw("UPDATE tickets set booked_by = 1234567 where id = 1").Exec(); err1 != nil {
        fmt.Println("Error 1", err1)
    } else {
        if _, err2 := o.Raw("UPDATE tickets set locked_by = '45440000_q' where id = 15").Exec(); err2 != nil {
            fmt.Println("Error 2", err2)
        } else {


  • after the BEGIN statement everything is a single transaction, and until the COMMIT command is passed, the transactions are not recorded in the database.
  • In the first if loop, the SQL query will execute without any error. So it will enter the second if loop.
  • In second if loop, however the integer column locked_by is trying to be set with a string value ‘12345_string’. This will fail.
  • So if the transaction was not rollbacked properly, the value in booked_by is supposed to be 1234567. But see it for yourself!
  • because the COMMIT was not called the transaction was not recorded in the database.
  • Only if all the Raw sql query executions succeed, then is when COMMIT is send.
  • So we get a transaction. (This is not the ORM specified way of doing it. I will blog on it later.)

Now try changing the string value assigned to locked_by with an integer value, and you will see both the values are assigned. because the transaction executed successfully.

The transaction failing and rollback executing code:https://github.com/sumitasok/go_packages/blob/master/mysql/orm_raw_multiple_query_return.go

Dont forget to change the mysql config.

And the King and his family lived ever after 🙂

Raw Sql query to fetch mysql table row count using beego ORM

Raw Sql query to fetch mysql table row count using beego ORM

import package beego orm

package main

import "github.com/astaxie/beego/orm"

We have to initialize the mysql connection, for that we have to import the mysql dapter for golang

add  `_ "github.com/go-sql-driver/mysql"` to the import statement

let us initialize the connection

func init() {
  orm.RegisterDriver("mysql", orm.DR_MySQL)
  orm.RegisterDataBase("default", "mysql", "mysql_username:mysql_password@/db_name?charset=utf8")

We register the mysql Adapter here, and then Register Database

Couple of things to note,

1. We need to have a “default” connection,

2. database has to be specified again, here it is “mysql”

3. “mysql_username:mysql_password@/db_name” replace them with your credentials. You are running it on local machine and the charset is utf8 is my assumtion (just keeping the scope limited)

Lets say you have a Table called Visits with columns id, name

So we create a struct, that will act as the Model for the table

type Visits struct {
  Id int
  Name string

Now we have to register the Model to the ORM

in init function, we add `orm.RegisterModel(new(Visits))` after the existing lines of code.

Time to fetch some data,

create your main function

function main() {
  o := orm.NewOrm()

you create an ORM instance, tell it which config to use. We have created a default one. This means you can define multiple databases

The query we want data from is

select count(*) as Count from visits where name  = 'name';

and the return has to be an integer value, the count

lets create the call, and pass the value for name as a parameter, so we can show some runtime control over the query.

  var count int
  o.Raw("select count(*) as Count from visits where name = ?", 'plant').QueryRow(&count)

add this to your main function and print the value, you will have got it!

your whole code look something like this

package main

import (
    _ "github.com/go-sql-driver/mysql"

func init() {
    orm.RegisterDriver("mysql", orm.DR_MySQL)
    orm.RegisterDataBase("default", "mysql", "mysql_username:mysql_password@/database_name?charset=utf8")


type Visits struct {
    Id   int
    Name string

func main() {
    o := orm.NewOrm()

    var count int
    o.Raw("select count(*) as Count from visits where name = ?", "1").QueryRow(&count)


get the code here: https://gist.github.com/sumitasok/bfaa8a7194d3532878e9#file-orm_raw_query_integer-go

couple of things, for using beego/orm you have to get it. Run go get github.com/astaxie/beego on your console

and to use println, import fmt package.

How me ? – Experience Training Students at PA College of Engg.Mangalore, with Python.

One fine Wednesday evening one of my friends Sarath, whom I met only a week before,called me. Though was working late, I was relaxed as a bigger chunk of code I wanted to deliver was delivered and was happy with the outcome. Basically that means, I was all in a very very good mood.  


But Sarath was not in the same mood. He started the conversation saying, Sumit, this is a distress call. I was like, why mate, what happened ? Then he briefed his position to me.


Sarath is a very motivated and socially responsible guy who takes huge efforts to push the Free Software Movement of Karnataka forward and FSMK had offered to train students around Mangalore Engineering Colleges which was gathered under PACE‘s initiative to bring open source(GLUG Mangalore) to the kids.Towards that final moment, when there were only two days for the event to happen, the Guys who had offered to go with Sarath to the session backed off. His need was to fill the positions.


I being a rails guys for really long and my knowledge of Python dated even before that, obviously would have had to think twice. But donno what, I just said, Dude! that is it! I’ll go to Mangalore.

It was for the first time I was going to see those guys who were going to be my fellow colleagues for the rest two days and there were as usual thoughts, how they would be.The organisation committee had put 1-2 years extra in the age field for everyone(in the bus ticket they sent me). So I was under an impression to see some really “experienced” guys up there.


Well for my luck, all were fantastic guys!


I met Chandrashekar, who works as a Team lead, at ZeOmega, Emil and Mayank who works with SourceBits. They were equally cool when they discuss technology and other stuffs. I got to know a lot of new stuffs from there. And to my surprise, Chandrashekhar was working on ETL (Extract Transform Load) projects for a while now.It is important for me, because the project that has took away my sleep and movies from my life for the past 1+ month was ETL. He helped me with a lot of his experienced opinions and new techniques to handle stuffs. Have to get more from him. Plan was to do it on the Day 1 evening, but that got switched for a movie plan later 😛


Chat with Chandrashekar was more on the topic Philosophy than on Technology through the travel. He just has got a lot of experience thinking on philosophy. I being pretty open for discussions on philosophy, just loved it!


Day 1, morning, we were picked up from the bus stand and was dropped at PACE’s guest house. Have to mention, the food was awesome. And that was not the thing that surprised, us. The food was the same that they served at their hostel messes, and we started feeling jealous for the kids here 😀


Had a power nap and we were ready for the day. Not knowing what and how the scene would be there in the college. We were introduced to the HOD of PACE Mr. Ganesh. Such a phenomenal guy. He is an asset for them. The students here are all words, when they talked about their HOD. He deserved that, of course..

 And rest of the story is at here(day 1) and here(day 2)

Day 1 of 2 days with my py-kids

Day started with first intro by Chandrashekar. He had created the correct slides, and gave a perfect 101. It was sad that guys and gals where not even ready for that. FSMK, GLUG and all FOSS orbs out here has to do a serious work on this.they need to know what open source and how cool is it.
First lab session, and I was assigned in Lab D. So sleepy and inactive guys and gals to deal with.
     But, I’m happy the Gender ratio was equal and better on the girls side. This is something the Open Source community has yet to improve on. I was trying to follow the questions Chandru had set already. And I couldn’t feel that the kids where gaining anything, because the time frame we allotted them was not enough for them to catch up.
After asking questions and getting all eyes staring at me, i started saying, guys, responses please. That is what would take you into height you have to fly. Respond when you know something. Respond, and say, when you , don’t know something. Which essentially means, respond, no matter what.
After lunch second session by Chandru was on read and write – Files  and Classes. And there where four questions for the kids to work on. And right after his talk when people was still not responding, I thought it is time for me to step in and give them a talk about how they should see themselves if they have to rock in this industry.
It was time for me to be in action – My Lightning talk
I was not so happy with the 0 response principle these kids carried. I wanted them to wake up and stand for themselves. Forget about the company taking you in and training you and feeding you. I wanted them to understand the need of working for themselves.
After giving a quick talk to the all four teams it was time to be back back at the Lab session.
This time I did not start with the coding part. Instead I gave a 10 mins talk, a motivational talk. On how the job would be. How hard it would be to survive. How you should struggle. And more importantly how to get into the best companies out there, rather that waiting for MNC’s to come and pick them in, and put them into the companies choice of technology – which mostly would be the legendary manual testing.
I tried to achieve the ‘open source and how cool is it’ part here. Hopefully some must have grabbed something, if not all things, and they never had any hands on experience with this. Or may be was not aware that such a cool community exists.
I was under a tight schedule under my work, and when I accepted this offer to take session. All I wanted was to deliver some value to the community I belong to. The community which pitched me into a wonderful job. And is still caring for me by making me enthusiastic with its own mind blowing developments.
I told them, all I wanted to take away from here. All I can take away from here is just, satisfaction. Satisfaction, of teaching some students how to set their career in a beautiful and promising track.
Well  that went well, and I got really got responses from kids – that was unexpected.
It was time to start the lab, and I had a plan this time in my mind. I did not want to traverse the questions which they where asked to solve. Instead, I wanted them to understand the concepts. I collected the the 4 questions together and made it into a single question and started working.
The first two questions was file read and file write. The third was Class  and the forth was Dictionary.
I planned it like, create a Dict. That was done, and people pretty well started understanding how to set the key value pair and how to add/append data into it. Then it was creating a class to hold those data. Made them pass those data into the class and make an object of it. For this second short 1 hour session which also included a motivational talk, this was enough.
Had been asking them if they understand or not. If they do not answer when I ask ‘did everyone understand ?’ then the question gets changed ‘ who all did not understand  ? ‘
including both sessions, after 2.5 hours of effort, people starred responding well. At least they daed to say, they did not understand some concepts, which was valid. Coz, I even had to face somebody who did not understand and array and relations ship between index and value in it. Which is totally fine. After all, I’m there to explain ( though supposed to be explaining PY that data structure concepts).
I gathered all around my laptop and showed then step by step. Asked them questions. And stressed until they decided to give answer.So here is the thing, If they don’t know answer, they don’t talk. They don’t even give a try, or a guess at least. All I would have asked would be a yes or no question, and a guess is pretty easy there. But I was patient enough to wait until till decided to give me the answer. though it was wrong, I don’t care. I know they are fresh heads and they are not expected to be correct all the time. But for me they are future engineers under constructions, and have passed 3 years under the build process called Engg. classes. I expect them to be responsive, and alive.
BUt towards the end, either they developed a confidence within them, or developed a trust in me, that, they started to respond pretty well. They started participating. And when there is a two way participation happening there is nothing better a session would need of being effective.
I’m hoping I did justice to them on Day 1.
Well it was time for some evening masthy (fun) and we will a cool college guy went for a movie, prisoners. And luckily that was a fantastic movie. We had a wonderful time. And best part was, we never felt we just met each other last night. All were as if we were friends from the college, and rather, we were from college! It was a very pleasant and for some reason nostalgic night.

 Day 2 overwhelming…is coming…here

Day 2 of 2 day with my py-kids (Experience Training Students at PA College of Engg.Mangalore, with Python.)

Today is day 2, which is complete 3.5 hours lab session. I am preparing for the day. I have travelled all the way to contribute. To the new guys who are yet to step in to the industry. All I want to take back is a satisfaction that I made some people learn. And I believe I’ll do that happen today.


I was hoping the guys and gals will be pretty energetic today.But what happened was not what I expected to get. They were the same. Not at all responding. I had to spend 20 mins talking to them, giving enough gaps, that the class will not proceed without them responding. Ultimately, when I saw that I was losing and so I tried a different approach. I wanted them to see me as a friend rather than a trainer. They were still in the school college stage where the guy standing against them across the other end of class room is a Sir or a Teacher. After repeatedly asking them to call me by name over ‘Sir’.


‘saar’… again, I couldn’t get many of them to forget this word…


But having said all these, all the guys and gals there where lovely… Given a chance again, I would take classes for the same batch any number of times…


I couldn’t find a face that was there yesterday btw. Though there must be something wrong with my class that I lost a student 😛

But later found out that since a parallel batch had a drop in students,my lab had issues with internet.


After calling all of them close to me, I started showing my laptop screen to them and a picture of mine sleeping on the beanbag at the office. That was one step that brought them close to me. They almost started feeling free. Well that was one correct step, as some feedback later included this instance being promoted by them. What I was trying to tell them was, if you have to get this freedom at work, you need to make yourself worth and for that you will have to struggle. And this is where it all begins, start getting involved, and start it with responding. Today I’m asking you people. Tomorrow, when you might be in front of me where I’m interviewing you, I wouldn’t even ask you anything and you might have to love yourself all by your words. So start talking. Learn to express yourself.


Then slowly started showing them small code snippets running in my console. Occasionally triggered my irb(interactive ruby shell) and showed them the python equivalent in ruby. Well the real need arouse, as I’m very much used to ruby that I was typing everything the ruby way in py shell, and was failing at times. And thus had to show them, that’s how it is in ruby.

But that very well helped them understand language as a medium, and I hope that would have set their mind understand scripting language principles.


Asked them questions, why this is like this and that is not like that kinda questions.

What is the type of dir(‘str’)

whats the type of dir(str)


and so on…until people started giving me correct answers. I was feeling like they are getting the concepts correct by this.


Once I started feeling like they are on right track, I asked them to group themselves into four teams, without looking which college they are from. They all gathered that way and now it was time to get the real game running.


Motivational talk, Career guidance was among topics I concentrated on, unknowingly. Python was an added advantage for them. Thus says their feedback.They are pretty happy about that.

I was lucky enough to be assigned with the most crowded lab, as the lab I got was the most spacious one. Over all, in every means, I was having a fantastic time there. More than teaching, I had learnings. I learnt to throw hesitance away and have definitely lot more.



Thanks to Anubha Upadhya M for all her help proof reading and making this post cute as it is now!


This too will fade away, with what all did go away,..

memories are hard, but most of them not, if you are smart

time to get some fresh air, when deep under rush of fate unfair
or run like radical, as emotions are nothing but chemicals…
this too will go away…with all that have faded away…
never cry for a pain less than the pain you cried earlier…
for no pain is pain when your eyes have paid em all in tears…
started these lines sad to wash em all deep and far away
coz what i define now, is what i pass through right away…
as they say, the gap in your life is all you’ll have to pay
coz what you have in your life is all you let to stay
so quit the cry and above par the hurdles all the way
love thy self and get to know what life has to say… 

Accessibility: resurrection of a web developer.

My introduction to Accessibility.

As any other developer in his initial stage, I too started out my programming at college, where there was no one to guide me. I remember writing rhtml(ruby html wrapper) when I did not know what html was.  Later I realized the importance of html. Its been years of web development and it was recently around a year back when I learnt what semantic html is, that changed the developer in me. The guy who was concerned with code quality and web security, realized that he was contributing to bad, html code. With my company’s support, we together worked towards achieving web standards for our app which earned us Level AA certificate and happy customers like NDIS(National Disability Insurance Scheme) Australia who poured out their kind words of appreciation on our work. Today I’m keen on creating accessible prototypes for the front end, spreading awareness across the team and across the community, I’m trying to take my learnings to everyone I can share it with and making them a web standardized developer from yet another web developer.

What steps need to be taken towards these goals ?

  • Spread awareness and learning among Web developers
  • Make companies insist their developers write better and accessible web/apps. And follow web standards.
  • Motivate more developers into accessibility and need for that.

Thanks Nikhil, for proof reading this article.

My Project’s Take Away from PyCon’s Pandas session by S.Anand

I being a regular rails guy since last 5 years, my appearance at the Pandas session was exclusively a project related one. And I already had hear high about the speaker of the session S.Anand of Gramener. My knowledge with python was of working for 6 months, that too around 5 and a half years back. So, I consider myself as a beginner when it comes to python.
The Project that I was working with had huge Data ETA (Extract Transform and Load) running on ~350 databases, with ~40 tables in each. The average rows count of visits table alone accounting to nearly 2 million rows each in each database. My project deals with moving all these data into one single database. Lots of number crunching has already gone into the population of visits table, and the data in some of the tables dates back to 5-6 years. The new implementation of visits are so complex that the number crunching pattern itself has been improved. So huge Transformation is manifested.
Above everything, we are running on a tight ETA, and very short window of down time for the migration.
My team had already put everything aside and started the work. But, I wanted to explore if we are missing any better implementation by any means. And that brought me to pyCon.
Talking about a minor complicated scenario. Where earlier we had a single table, now we have divided the columns in the same table into two different tables with a has one relationship between them. And the rows in the table are moved on to three different tables. It is evident that there will be various changes that was introduced to depict this big difference in the ER(Entity relationship).
(OLD) TableABCDetails 
TableA \
TableB – DetailsHasOneTable
TableC /
What makes Panda a Perfect fit for our need ?
Panda has got read/write(IO) facility for CSV, JSON, EXCEL, HDF, STATA, HTML, CLIPBOARD, PICKLE and our own SQL.
The session though was using CSV as the data source. The fantastic ORM and DSL provided by Pandas, will only want us to know a single difference
which is,
read_csv(‘…’) vs read_sql(‘…’)
to_csv(‘…’) vs to_sql(‘…’)
Updating a new Column with data, or adding a new column with data derived through an equation is a single step. No iteration involved, at least in the developers code. These all are again going to go into mysql as sql bulk create.
Complex calculations turns into a simple one-liner this way.
…a lot more of it’s feature will be covered in my later posts…
Get the database dump, and load it to Pandas, Do the Transformation, and them export as Sql. And source the Sql output from inside the target database. tada.
What all are the technical gains ?

Py has got a fantastic GC(garbage collector) compared to ruby, If I’m not wrong.

Py execution is fast compared to ruby.
Directly doing a bulk update on sql, than updating by iteration under for…loop in ruby using Active::model create method is much faster. And consumes very less memory. Will provide a Bench mark later in my next post.
The overhead of having huge data in memory is also less when run by pandas over ruby on rails. As Anand mentioned, pandas is the fastest and efficient way of dealing with Big-data with python, and probably with many other languages. Any way, my experience at the work shop confirms, that it is brilliantly fast.
In terms of code development time,
 – since no for…loops and similar interpolations are done the traditional way, that saves the dev a lot of time while coding the data transformation part.
In terms of process execution time,
 – The absence of ruby For…loop itself adds efficiency, and python has got better underlying C implementation.
 – Above all of that, In pandas, a lot of thoughts by data scientists and mathematics evangelists have been put in, making it cutting edge at what it does. It exclusively does handle big-data manipulation. It is born to maneuver custom code developed by a regular web/software developer.
…Currently our ETA doesn’t support such a huge change in technology usage, but I’m so impressed(and resting high hopes) with this that I will definitely make time to re-implement my project with Pandas/Python and probably that might get Acceptance too, seeing the whole lot of advantages this method holds.
All of those will be another post for sure…
A big thanks to Anand for his patience, brilliant presentation and technical skills. His knowledge is vast, and his humbleness is deep. I’m impressed by your talk.

Tabindex, using it right is all about not using it.

We know, tabindex exists for a purpose. But it has its own use. Like every other thing, we tend to over/mis-use tabindex as well. Today the Web has changed, and there are better approaches to handle the use cases that tabindex used to in the past.

I would say that the only place where using tabindex is legitimate is when using −1 as value. −1 is used to make an otherwise not tabbable element tabbable. Best use case for tabindex −1 is for skip_to_links. A skip_to_link is made by setting the href as the id/name of the receiver element. And the element has to have a tabindex −1 to receive the tab. Elements like link(anchor), input fields(form controls) are designed to receive keyboard tab. And for elements that cannot receive tab, we use this method to make it tabbable.

<a href="#conta11y" id="jmp2Cont"
    title="Jump to Content">Jump to Content</a>
Land at:

<a href="" id="conta11y" tabindex="-1" title=""></a>
For everything else tabindex is evil.
You can use skip-to links, but html5 has come with semantic elements like <header> and <footer>. Assistive Technology (AT) understands these objects as landmarks and provided option to jump to them directly. This way also helps user to jump to content easily as soon as the page loads, than having to navigate through many navbar links to reach the main content.
ARIA (Accessible Rich Internet Applications Suite) can be used for the same. If role=“main” is added, AT will understand  that this is the most important part of the page.
So, now we have an alternative for skip-to links as well. Let’s not use Tabindex.
The bad sides of using Tabindex are listed below. They are about development practices and code quality.
  • Code becomes hard to maintain.
  • For minor additions, we will have to do extensive tabindex changes, like adding tabindex values towards the next tabbable elements.
  • We are achieving some functionality by addition of a new attribute tabindex, when we can achieve the same by (probably) reducing the number of unwanted HTML elements (like excess DIVs used) and by using proper HTML semantics.
The HTML itself has to be constructed in such a way that it is semantically meaningful.
The best way to make sure the HTML we wrote is semantic, is to represent it as a tree. Then see which all elements are placed at what level in the tree. If the order in the tree is not even, then it is a sign that our HTML is not semantically correct.
This also helps to reduce unwanted HTML elements. We tend to write a lot of DIVs only to use with CSS. This is a smell. We should reduce the DIVs and utilize CSS to the maximum to layout the page as we want.
Use proper elements like UL-LI, H1, H2, H3, P etc to define content, instead of using DIVs.
There are cases where people uses DIVs for lists. Certain plugins also do the same, making things out of the way.
There are people who write a lot of DIVs to show a list of buttons. Say, for showing a list of tabs, navigations etc. The only proper way to display it is to show it in UL-LI lists or OL-LI as required. Even people who use LI, add a DIV within the LI, which is an overloaded use of div.
    <div>Wrong way of doing it!</div>
We don’t need an extra DIV there. If we need to add any styles, we can add it on the LI itself. Just make sure you select the element using a class name, than using the element itself, in the style sheet.
<pre><li class=“list”>Content</li>

<style type=“text/stylesheet”>
  .list { color: blue; }
is preferred over
<pre><style type=“text/stylesheet”>
  li.list { color: blue; }
This makes the code independent of elements and a change at a later point becomes easier. As an Accessibility POC for my company, I prefer this approach as that makes my job of making the elements HTML standards compliant easier. This method reduces my job, at least at the CSS level as fewer things are prone to break in this approach.

Thoughts ?

Thanks to @unnitallman (Unnikrishnan KP) who took out his time to proof read this article.