Palabras reservadas de MySQL como nombre de modelo

Al generar un modelo con una migration en ruby on rails creamos una tabla en la base de datos. El nombre de esta tabla será igual a la forma pluralizada del nombre del modelo. En MySQL esta migration generará una sentencia sql de la forma:

CREATE TABLE model_name_pluralized (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY,
`created_on` date DEFAULT NULL, `name` varchar(255) DEFAULT NULL) ENGINE=InnoDB

Como puedes ver, los nombres de las columnas están entre comillas pero el nombre de la tabla no. Si utilizas como nombre de modelo la forma en singular de una palabra reservada de MySQL, la migration generará una sentencia sql que dará un error como:

Mysql::Error: You have an error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near 'databases (`id` int(11) DEFAULT NULL
auto_increment PRIMARY KEY, `created_on` da' at line 1: CREATE TABLE databases (`id` int(11)
DEFAULT NULL auto_increment PRIMARY KEY, `created_on` date DEFAULT NULL, `name` varchar(255)
DEFAULT NULL) ENGINE=InnoDB

La semana pasada leí unas transparencias de Josh Susser (Laying Tracks) que me animaron a escribir un parche para este problema.

Antes de escribir nada miré si podía encontrar algo relacionado. Encontre algún ticket similar en el trac de Rails:


El ticket más interesante de estos es el #4905, donde se corrigen todas las sentencias MySQL que pueden generar ese error. No se porque pero este parche no está incluido en el código de rails a pesar de ser del 25 de mayo de 2006. El tickert #7850 está cerrado al considerarse duplicado respecto el #4905. Y la história del ticket #3631 acaba con la frase "no usar palabras reservadas", lo cual en mi opinión no es la mejor solución.

En resumen, el problema existe (no se pueden crear modelos con nombres como "database", "exist", etc ...) y el parche también existe (#4905). Entoces,
que se debe hacer ahora para arreglar este problema?

Etiquetas: , ,

Posted by Spejman at 12:20 p. m. | 0 comments read on

Copia de seguridad de bloglines

Si eres usuario de bloglines (lector de feeds online) probablemente guardes los posts que te parezcan interesantes utilizando la opción "keep new".

Después de usar este lector de feeds durante un tiempo, la cantidad de posts interesantes que he guardado así es importante. Estuve pensado que no me haría ninguna gracia perder estos datos, por eso he hecho un script que hace un backup de estos posts en un archivo xml.

Este script me ha servido para probar dos librerías muy útiles de Ruby: mechanize y hpricot. Mechanize permite navegar por web utilizando comandos muy simples como podrás ver en el script. Hpricot permite parsear documentos html y xml de manera muy fácil e intuitiva.

Para usar el script necesitas instalar las siguientes librerías:

gem install json
gem install activesupport
gem install hpricot
gem install mechanize


Y aquí dejo el script, creo que se entiende bastante bien lo que hace. Espero que os ayude bien a hacer un backup de vuestra cuenta de bloglines (recuerda cambiar los valores EMAIL y PASSWORD) o bien a aprender un poco como funcionan mechanize y hpricot.

require "rubygems"
require "hpricot"
require "json"
require "mechanize"
require "active_support"

# Reads a bloglines javascript tree structure that has all
# feeds data.
def read_tree( tree_base, label = "" )
tree_base.each do |tree|
if tree["kids"]
read_tree tree["kids"], label + "/" + tree["n"]
else
@feeds << [tree["n"], label, tree["kn"], "http://www.bloglines.com/myblogs_display?sub=#{tree["id"]}&site=#{tree["sid"]}"]
end
end
end

# Add more memory to hpricot otherwise couldn't load some webs.
Hpricot.buffer_size = 262144

agent = WWW::Mechanize.new
page = agent.get 'http://www.bloglines.com/login'

form = page.forms[1]
form.email = 'EMAIL'
form.password = 'PASSWORD'

page = agent.submit form

# Get the bloglines sindicated feeds
menu_page = agent.get "http://www.bloglines.com/myblogs_subs"
start_text = "var initTreeData = "
end_text = "\n;\n"
js_feeds_tree_str = menu_page.content[menu_page.content.index(start_text)+start_text.size..menu_page.content.index(end_text)]
feeds_tree = JSON.parse js_feeds_tree_str.gsub("\\","")
@feeds = []
read_tree(feeds_tree["kids"])

puts "<bloglines_saves>"
@feeds.each do |feed|

page = agent.get feed[3]
doc= Hpricot(page.content)

# get the content of all saved feed posts
content = ((doc/"body")/"td.article")
next if content.empty?
puts "<feed name=\"#{feed[0].strip}\" folder=\"#{feed[1].strip}\">"

# Iterate each saved feed post
((doc/"body")/"a.bl_itemtitle").each_with_index do |title, index|
puts "<feed_save title=\"#{title.inner_html.strip}\" href=\"#{title.attributes["href"]}\">"
puts content[index].inner_html.to_xs
puts "</feed_save>"
end
puts "</feed>"

end
puts "</bloglines_saves>"

Más información:

Etiquetas: , ,

Posted by Spejman at 7:32 p. m. | 1 comments read on

Instalar sqlite3 para rails en Ubuntu

  1. Instalar sqlite y sus librerías de desarrollo:

    sudo apt-get install sqlite3 libsqlite3-dev

  2. Instalar la interfaz sqlite3-ruby para poder conectarnos a la base de datos sqlite3 desde Ruby.

    sudo gem install sqlite3-ruby
    (Si aparecen varias versiones a escoger, seleccionar
    la última versión para ruby.
    )

  3. Crear la base de datos, realmente solo creamos un archivo vacío que es lo único que necesita sqlite3.

    touch database_name_dev.db
    touch database_name_test.db
    touch database_name_prod.db

  4. Configurar la aplicación Ruby on Rails para usar estas bases de datos.
    Modificar el archivo config/database.yml:

    development:
    adapter: sqlite3
    database: db/database_name_dev.db

    test:
    adapter: sqlite3
    database: db/database_name_test.db

    production:
    adapter: sqlite3
    database: db/database_name_prod.db

Listo! a partir de aquí puedes desarrollar tu aplicación rails usando sqlite3 como base de datos.

Etiquetas: , , ,

Posted by Spejman at 8:12 p. m. | 2 comments read on

Congreso NAACL HLT 2007

La semana pasada estuve en el congreso NAACL HLT (North American Association for Computational Linguistics Human Languages Technologies) en Rochester (New York). Allí presentamos un artículo sobre adquisición automática de información léxica ("Automatic Acquisition of Grammatical Types for Nouns", BEL, N.; ESPEJA, S.; MARIMON, M. PDF).

El congreso fue muy interesante, destacaría que hay muchísimo trabajo por hacer en el área de la lingüística computacional. Google, que está muy metido en estos temas, presentó sus resultados de traducción automática. Parece que son los mejores utilizando métodos estadísticos para traducir del chino al inglés. De todas maneras sólo tienen un 40% de acierto utilizando TeraBytes de datos! Lo que permite intuir la complejidad de la tarea.

Esta semana en Estados Unidos también me ha permitido hacer un poco de turismo y comprobar que efectivamente, Estados Unidos es como en las películas. Es muy gracioso ir viendo como todo lo que aparece en las películas lo encuentras por la calle.

A continuación os muestro algunas fotos del viaje.
Nueva York:

Rochester:

American way of life:

Cataratas del niagara:

Etiquetas: , ,

Posted by Spejman at 8:50 p. m. | 0 comments read on

Cambio de precios en Amazon S3

Amazon ha cambiado su política de precios en su servicio S3 (almacenaje), lo que también afecta a los servicios EC2 (computación elástica) y SQS (paso de mensajes).

Los cambios se reflejan en las tarifas de uso de ancho de banda. Anteriormente el precio era de $0,20 por GB subido o bajado, independientemente de las peticiones realizadas.

En Amazon se han dado cuenta de que les cuesta mas atender peticiones que subir o bajar datos, por lo que cobrarán por un lado el ancho de banda utilizado (subir o bajar datos) y por otro lado las peticiones:
  • $0,10 por GB para todos los datos subidos.

  • $0,18 por GB para los primeros 10 TB de datos descargados al mes.

  • $0,16 por GB para los siguientes 40 TB de datos descargados al mes.

  • $0,13 por GB para los datos descargados al mes a partir de 50 TB.

  • $0,01 por cada 1.000 peticiones PUT o LIST.

  • $0,01 por cada 10.000 peticiones GET o otras (excepto las DELETE que son gratuitas)


Estos cambios se harán efectivos el 1 de Junio de 2007.

Etiquetas: ,

Posted by Spejman at 11:05 a. m. | 0 comments read on
Recommend Me


XING
View Sergio Espeja's profile on LinkedIn













Enlaces