This ORM looks interesting

Except when I do, and have done for a while. Pretty sure I've even made a drunken thread about it.

No matter how many times I say it though, no one seems to believe it.

For the last time, I was a moron. Live and learn. Although I will say it drives me nuts how you post so many different new techs, how can you possibly keep up with them all?

Also:
37339487.jpg

1. scan HN and /r/python
2. talks to other people who make money from writing smart code often.
3. have several projects that can constantly be refactored with new techniques or technologies to avoid launch ;)
4. avoid ruby.
 


The pony guys are super responsive when emailed for help, they sent me some docs they hadn't published yet to clear some stuff up. I think I'm close to having my ideal webdev setup now with pony, flask-classy.
 
  • Like
Reactions: Uptime
^^ I've never understood the desire for developers to use this type of thing. Why not just use SQL?

Code:
SELECT * FROM table WHERE name = 'John' ORDER BY age

Isn't that easier than messing around with code like above? Not to mention when you get into more complex queries while displaying statistics and things, then using SQL is without question better.

One of the biggest reasons to use an ORM like Rails' ActiveRecord is automatic query sanitation. Also, writing idiomatic ruby code to access your data later is a lot more comfortable for me than writing raw SQL, though I have written raw SQL to optimize some slower db calls in the past.
 
One of the biggest reasons to use an ORM like Rails' ActiveRecord is automatic query sanitation.

Sanitation is quite easy to do yourself without convoluting everything into a mess though.


Also, writing idiomatic ruby code to access your data later is a lot more comfortable for me than writing raw SQL, though I have written raw SQL to optimize some slower db calls in the past.

Yeah, this I could see, and I think(?) Python and Ruby do excellent jobs with it. For example, right now in PHP for me to grab and update a row, I would use:

Code:
list($exists, $row) = db_cget('table_name', $id_number);

db_update('table_name', $id_number, array(
     'name' => 'Mike Smith', 
     'email' => 'mike@gmail.com')
);
Whereas the PHP equivalent of say Python or something would be more like:

Code:
$row = $table->find($id_number);
$row->name = 'Mike Smith';
$row->email = 'mike@gmail.com';
$row->save();
The latter is definitely more efficient and readable, and probably something I should be implementing into my own database library. However, I'm still adamant that if you want to call yourself a developer, you should know and use SQL. And you definitely shouldn't be allowing a software program to write your database schemas for you (not saying you do), because that's just sloppy.
 
It's not sloppy, it's not repeating yourself, the ORM is taking code structures, and, in a predictable way, converting them to database table structures.

During development, it's easy to change the structure in the code, while being able to easily revert to a previous structure (by reverting git commits / switching branches) and then by running 1 script, creating the entire database from scratch.

I have never done this, but I imagine that for certain projects, being able to dynamically create ORM models (classes), and therefore database tables could be advantageous.

I'm pretty sure that everyone in this discussion knows SQL to a decent level, it doesn't necessarily mean we should use it whenever interacting with a database.
 
I'm actually a little taken aback that you're advocating dynamic generation of database schemas. That's a little surprising coming from you. :)

Nonetheless, I'm not about to spend the time to write up a 50 point list as to why that's a bad idea. I couldn't imagine just throwing a bunch of data around in the code though, and hoping the ORM manages to make a decent structure for it all.
 
Sanitation is quite easy to do yourself without convoluting everything into a mess though.




Yeah, this I could see, and I think(?) Python and Ruby do excellent jobs with it. For example, right now in PHP for me to grab and update a row, I would use:

Code:
list($exists, $row) = db_cget('table_name', $id_number);

db_update('table_name', $id_number, array(
     'name' => 'Mike Smith', 
     'email' => 'mike@gmail.com')
);
Whereas the PHP equivalent of say Python or something would be more like:

Code:
$row = $table->find($id_number);
$row->name = 'Mike Smith';
$row->email = 'mike@gmail.com';
$row->save();
The latter is definitely more efficient and readable, and probably something I should be implementing into my own database library. However, I'm still adamant that if you want to call yourself a developer, you should know and use SQL. And you definitely shouldn't be allowing a software program to write your database schemas for you (not saying you do), because that's just sloppy.

I don't think it's sloppy at all to use an ORM or dynamic schema generation (though I don't think this library is the same as rails which just has strong db conventions that can be overridden when necessary).

My opinion has always been that the rails core devs are insanely smart and will collectively always be better coders than I. Because of that, I follow their lead and use what they use. It has made me a better coder.
 
I'm actually a little taken aback that you're advocating dynamic generation of database schemas. That's a little surprising coming from you. :)

Nonetheless, I'm not about to spend the time to write up a 50 point list as to why that's a bad idea. I couldn't imagine just throwing a bunch of data around in the code though, and hoping the ORM manages to make a decent structure for it all.

It might rarely be useful in production (that crazy dynamic part of my post). In development, changing the database schema on the fly is incredibly useful.
 
I must be missing something here then. When I look at a table, I see things:


  • TINYINT(1) means it's a boolean (1/0)
  • ENUM() -- I know exactly what values are allowed, helping me gauge what's going on
  • BLOB -- Binary data
  • VARCHAR(255) -- String
  • TEXT / LONGTEXT -- Large string (eg. contents of an article, page, etc.)
  • Indexes -- helps me gauge what type of data the software is grouping / searching by the most
  • Foreign keys / dependencies
  • Auto increments columns -- so I know what's unique and what isn't.


And loads of things like that. In my mind this is critical to the development of quality software, and there's no way an ORM can design a table structure as well as a human, because the ORM can't read our minds. You guys have just forgone this, in exchange to save a little extra time?

Or how about just simple date functions?:

Code:
SELECT year(date_added) AS year, sum(amount) AS amount FROM payments GROUP BY year(date_added);

UPDATE recurring_payments SET next_payment_date = date(date_add(next_payment_date, interval 1 month)) WHERE id = $id;
What happens if the ORM labels it a VARCHAR column instead of DATE / DATETIME? Those above statements are just going to throw an error. Let alone more complex SQL statements. Or what happens when you make a typo in the code? Instead of getting an error, the ORM will just add another column to the table.

I don't know, I'll shut up now.
 
From the Pony docs:

Code:
class Person(db.Entity):      
  name = Required(unicode)      
  age = Required(int)
Types are specified. Names of attributes (columns) are specified.

A typo will not cause a column to be created.

To make a datetime, i'd have an attribute of the model which is

Code:
date_added = Required(datetime.datetime)
Another example from the docs:

Code:
select((s.dob.year, avg(s.gpa)) for s in Student)
Change avg to sum and you have something close to your query.

Pony ORM 0.4 documentation - Even if you don't know python, it's not hard to follow.
 
I must be missing something here then. When I look at a table, I see things:


  • TINYINT(1) means it's a boolean (1/0)
  • ENUM() -- I know exactly what values are allowed, helping me gauge what's going on
  • BLOB -- Binary data
  • VARCHAR(255) -- String
  • TEXT / LONGTEXT -- Large string (eg. contents of an article, page, etc.)
  • Indexes -- helps me gauge what type of data the software is grouping / searching by the most
  • Foreign keys / dependencies
  • Auto increments columns -- so I know what's unique and what isn't.


And loads of things like that. In my mind this is critical to the development of quality software, and there's no way an ORM can design a table structure as well as a human, because the ORM can't read our minds. You guys have just forgone this, in exchange to save a little extra time?

Or how about just simple date functions?:

Code:
SELECT year(date_added) AS year, sum(amount) AS amount FROM payments GROUP BY year(date_added);

UPDATE recurring_payments SET next_payment_date = date(date_add(next_payment_date, interval 1 month)) WHERE id = $id;
What happens if the ORM labels it a VARCHAR column instead of DATE / DATETIME? Those above statements are just going to throw an error. Let alone more complex SQL statements. Or what happens when you make a typo in the code? Instead of getting an error, the ORM will just add another column to the table.

I don't know, I'll shut up now.

I can't speak for Pony because I'm not a python dude but for rails, you explicitly generate your schema via migrations where all column types are explicitly specified by the coder.
 
There's obviously a bit of confusion about how much magic an ORM does here that is probably getting in the way of the huge list of awesome, predictable things one can be useful for as well.

An ORM isn't going to look at a field defined in your application by the name "created" and automatically -- with an understanding of the English language -- know that you want this to be a date field. Likewise, it's not going to know that a "note" field in a music database might be a VARCHAR field but a "note" field for a contact form database would be TEXT field.

If a database doesn't already exist from which the schema can be interpolated, this needs to be defined in your models.

The value (for me personally at least) is in the flexibility and control that using an ORM gives me.

A few different scenarios where it very useful:

# Database Independant

If you have a site set up with fields only available natively with certain databases (e.g. ENUM, BOOLEAN, DATETIME) and you need to change your database to a different type for whatever reason, the ORM will take care of this without you having to change any code.

If you define a datetime field for example, your model will return a native Python datetime type regardless of whether that has been pulled from a mySQL DATETIME field or a sqlite VARCHAR field.

Changing the database that a site is running on is obviously not something that happens all the time, but it's another thing I don't have to think about when using an ORM.

In a more common scenario, let's say you want the ability to create/destroy hundreds of in-memory sqlite databases for use when running your using tests (if I had such things!). With an ORM this is stupidly simple using the same code that interacts with your production database.

# Automatic Joins

Quite simply, you define the relationships between table in the model declaration which makes accessing joined data stupidly simple.

# Migration

This was something I hated before working with SQLAlchemy, but now I have version control for database schemas and can generate the code to migrate between versions of the database automatically when changes need to be made.

The Alembic library can use the current model definitions, interpolate the structure of the current tables and painlessly generate the code required to move between the two.

# Form Validation

Extending the model definitions used by the database for form validation is very simple and something I've fucking HATED dealing with by-hand in the past.

# Sanitisation

As already mentioned by others, I don't need to think about escaping data or cooercing different datatypes into or out of the database either.

# Abstraction

Abstrating away from the dataase is a good thing for me personally. If models can make data accessible from my application in such a way that it's very much like native data types sitting around already, this is great for me.

As far as I'm concerned, the less I know about the existence of the database, the better.

Getting back to Pony ORM, this just takes the concept another step further and makes data accessible in a way that is even more similar to native Python.



I'm sure there are plenty of other benefits too but these stand out for me.

The choice to use an ORM is as fundemental as the decision to use a framework or not as far as I'm concerned, and there are very few scenarios where I wouldn't.

I literally can't think of a single reason *not* to use an ORM.

If I was cleverer than the collective genius of the people who wrote and tested the ORM code, AND my life was filled with an abundance of free time that I couldn't decide how to fill, I might consider writing my own code (but I still probably wouldn't).

Using an ORM is just another opportunity to stand on the shoulders of giants and it makes my life better.
 
I must be missing something here then. When I look at a table, I see things:


  • TINYINT(1) means it's a boolean (1/0)
  • ENUM() -- I know exactly what values are allowed, helping me gauge what's going on
  • BLOB -- Binary data
  • VARCHAR(255) -- String
  • TEXT / LONGTEXT -- Large string (eg. contents of an article, page, etc.)
  • Indexes -- helps me gauge what type of data the software is grouping / searching by the most
  • Foreign keys / dependencies
  • Auto increments columns -- so I know what's unique and what isn't.


And loads of things like that. In my mind this is critical to the development of quality software, and there's no way an ORM can design a table structure as well as a human, because the ORM can't read our minds. You guys have just forgone this, in exchange to save a little extra time?

Or how about just simple date functions?:

Code:
SELECT year(date_added) AS year, sum(amount) AS amount FROM payments GROUP BY year(date_added);

UPDATE recurring_payments SET next_payment_date = date(date_add(next_payment_date, interval 1 month)) WHERE id = $id;
What happens if the ORM labels it a VARCHAR column instead of DATE / DATETIME? Those above statements are just going to throw an error. Let alone more complex SQL statements. Or what happens when you make a typo in the code? Instead of getting an error, the ORM will just add another column to the table.

I don't know, I'll shut up now.

You have to look at your schema in the DBMS to make sure it was properly created.

If it doesn't make the type you want, the ORM should let you import the native field types:

Code:
from sqlalchemy.dialects.mysql import \
        BIGINT, BINARY, BIT, BLOB, BOOLEAN, CHAR, DATE, \
        DATETIME, DECIMAL, DECIMAL, DOUBLE, ENUM, FLOAT, INTEGER, \
        LONGBLOB, LONGTEXT, MEDIUMBLOB, MEDIUMINT, MEDIUMTEXT, NCHAR, \
        NUMERIC, NVARCHAR, REAL, SET, SMALLINT, TEXT, TIME, TIMESTAMP, \
        TINYBLOB, TINYINT, TINYTEXT, VARBINARY, VARCHAR, YEAR
Most of the other stuff you can specify in a supported DBMS, you can specify in the ORM when creating the table.

http://docs.sqlalchemy.org/en/rel_0_7/dialects/mysql.html#mysql-data-types
 
Alright, I guess for the majority of web development you guys are probably right, and know what you're talking about more than me. However, will still stay I think defining schemas via an ORM is a horrible way to learn, and everyone should learn proper SQL. I'm not saying anyone here specifically, but just a general principle. Same as I believe PHP is a horrible language to start off with, because it allows you to easily be a sloppy developer, and doesn't require you to learn the fundamentals.

Still don't like the fact this is how people are learning though. What happens when volume increases, and you have a table getting hammered 1,000,000+ times a day? If you all know is defining columns via an ORM, there's a decent chance you're not going to know what to do.

That, and I'm of the belief the database layer should handle *almost* as much of the load as it can. Most database engines have a wide variety of functions available, and I'm assuming are being very under-utilized due to ORM usage. This becomes especially critical if you ever syphon off the database to separate server(s) and/or implement database replication. In those cases, you need to have the database layer handling that load versus your front-end web servers.

Anyway, I'll shut up again now, and admit defeat. You guys were right. :) Oh, but any time you guys bitch about PHP as a newb language, or a lazy person's language, I'm referring you to this thread. :)
 
Alright, I guess for the majority of web development you guys are probably right, and know what you're talking about more than me. However, will still stay I think defining schemas via an ORM is a horrible way to learn, and everyone should learn proper SQL. I'm not saying anyone here specifically, but just a general principle. Same as I believe PHP is a horrible language to start off with, because it allows you to easily be a sloppy developer, and doesn't require you to learn the fundamentals.

Still don't like the fact this is how people are learning though. What happens when volume increases, and you have a table getting hammered 1,000,000+ times a day? If you all know is defining columns via an ORM, there's a decent chance you're not going to know what to do.

That, and I'm of the belief the database layer should handle *almost* as much of the load as it can. Most database engines have a wide variety of functions available, and I'm assuming are being very under-utilized due to ORM usage. This becomes especially critical if you ever syphon off the database to separate server(s) and/or implement database replication. In those cases, you need to have the database layer handling that load versus your front-end web servers.

Anyway, I'll shut up again now, and admit defeat. You guys were right. :) Oh, but any time you guys bitch about PHP as a newb language, or a lazy person's language, I'm referring you to this thread. :)

You're right -- I'm sure nobody in this thread disagrees that you should know SQL.

I'm also sure everyone in this thread with a history with ORM/SQL-generation tools knows exactly what the ORM is doing for every token of code they write. Else, you can't really claim competence in these tools.

After all, the purpose of SQL generators and ORMs is not to make SQL invisible and magical, but to address 90% of the daily rigmarole of stitching it all together the same way every day.

That said, you're right that ORMs only get you part of the way there. It can be a bit of a sandtrap that keeps you from learning the things that your ORM does't support (like functions/features specific to your database). However, coupling yourself to a database is something you should do deliberately because it helps you, not because your underlying database has feature X. And you'll probably use a library that abstracts it for you anyways. :)
 
Ohhh, quit making excuses for being lazy. You're killing quality and efficiency in order to save time, and you know it. :)

But no, I use a database library myself of course to kill the repetitive typing. Although I plan to update my shortly, thanks to various things I've seen linked to in this forum and elsewhere. That's one thing though, but I'll never be in support of not writing your own SQL code for your table structure / schema. In my eyes, database schema should always be defined in SQL and written by the developer no matter what. Just one of those things you can't cut corners on.