+ Reply to Thread
Results 1 to 8 of 8

Thread: Quick Python Help!

  1. #1
    rewegan is offline x10Hosting Member rewegan is an unknown quantity at this point
    Join Date
    Nov 2009
    Posts
    4

    Quick Python Help!

    I'm trying to have something selected from a MySQL table.

    I want the user to choose the table
    SO i have set the statement as so...

    Code:
    ("""SELECT * FROM `%s`""", (choice))
    So for example.

    If the user has entered "Science"
    I have choice = "Science"

    So why when I run this, it tells me that
    "Table 'atg_admin.'Science'' doesn't exist"

    (atg_admin being my database in use).

    When it very much does exist.
    If I actually type the word "Science" isntead of using %s, it works fine.

    Please help.

  2. #2
    misson is offline x10 Spammer misson is a jewel in the rough
    Join Date
    Mar 2008
    Location
    Libertatia
    Posts
    2,506

    Re: Quick Python Help!

    Note the exact quotation marks:
    Quote Originally Posted by rewegan View Post
    'atg_admin.'Science''
    The single quotes around 'Science' indicate a string, rather than a name. The backticks in the query might also be throwing things off.

    What is the exact value stored in choice? What method are you calling to prepare the query?
    Be sure to read all pages linked in this post; they have further information that should prove useful. When asking for help, make sure you follow Eric Raymond's and Jon Skeet's guidelines for prompt, accurate responses. Please answer any questions I ask; they're not rhetorical (probably). Any posted code is intended as illustrative example, rather than a solution to your problem to be copied without alteration. Study it to learn how to write your own solution.
    Misson, not Mission.

  3. #3
    rewegan is offline x10Hosting Member rewegan is an unknown quantity at this point
    Join Date
    Nov 2009
    Posts
    4

    Re: Quick Python Help!

    Ah you're right, it's the string thing. It's being taken from an HTML input and stored as a text string. How do I change that? Instead of the input type being "text" do I change that to something else (on the html page).

    And the back ticks are the only thing I could get to work, any form of quotes gives me a SQL syntax error. They have worked with everything else I've done.

    Thanks for the reply.

  4. #4
    misson is offline x10 Spammer misson is a jewel in the rough
    Join Date
    Mar 2008
    Location
    Libertatia
    Posts
    2,506

    Re: Quick Python Help!

    It really depends on what you're using to prepare the query.
    Quote Originally Posted by misson View Post
    What method are you calling to prepare the query?
    As it says in the sig, questions aren't rhetorical.

    Most drivers don't support parameterizing arbitrary portions of queries. Usually you can only parameterize atomic values. No lists, no names, no keywords, which means you'll need to interpolate the value on your own.

    Even if the driver supports parameterizing table names, you shouldn't pass this data via forms. To do so is insecure (it leaks information about internal structure) and couples internal structure with external logic. Instead, pass arbitrary values via the form, which you can use as dictionary keys (or resolve in some other way) to get the table names. That way, there's no worry about injection attacks, there's no information leak and internal and external naming are decoupled.
    Be sure to read all pages linked in this post; they have further information that should prove useful. When asking for help, make sure you follow Eric Raymond's and Jon Skeet's guidelines for prompt, accurate responses. Please answer any questions I ask; they're not rhetorical (probably). Any posted code is intended as illustrative example, rather than a solution to your problem to be copied without alteration. Study it to learn how to write your own solution.
    Misson, not Mission.

  5. #5
    rewegan is offline x10Hosting Member rewegan is an unknown quantity at this point
    Join Date
    Nov 2009
    Posts
    4

    Re: Quick Python Help!

    I appreciate your resonspes, and I apologize if I have upset you.

    I'm just a 17 year old kid in high school trying to get his software assignment done. I don't have a very strong computing vocabulary, and working with databases is very new to me. There really wasn't anything taught to us, and our only teacher during this process is google and forums. So I really have no understanding of what you just said. Don't worry about resonpding if I'm becoming frusturating, I understand what it's like dealing with an ignorant person.

    Once again, thanks for the replies.

  6. #6
    misson is offline x10 Spammer misson is a jewel in the rough
    Join Date
    Mar 2008
    Location
    Libertatia
    Posts
    2,506

    Re: Quick Python Help!

    Don't worry about being ignorant, just staying ignorant. As long as ignorance is merely a temporary state and not a central component of identity, you're fine in the computing world. Don't be afraid to ask what a spline is when you don't understand some jargon. What follows is a lot to go through; understand what you can now, and re-read it later for the rest.

    A bit of advice: selecting all columns (SELECT *) is generally a bad idea because it introduces a dependence on the order of columns and pulls unnecessary information from the database, which uses resources you don't need to use. The result is brittle code and requires more work, should you change the order of the columns or insert additional columns into the table. Also, the code that handles the response depends on specific columns; selecting all columns makes this dependency implicit rather than explicit. Better to explicitly name the columns you need in the SELECT statement.

    To separate the table names used in the database (which are internal to your application, and shouldn't affect anything the user sees) from the values used in the form, here's a simple example using a dictonary:
    Code:
    subjects = {'sci': 'Science', 'mth': 'Math', 'lit': 'Literature', 'art': 'Art', 'dflt': 'Science'}
    # Preconditions:
    #    db.name == 'atg_admin'
    #    columns holds column names as a string, e.g. columns='`year`, `teacher`, `topic`'.
    # It doesn't come from user input.
    
    # If choice isn't a valid subject, use the default subject.
    # Could also abort action & print an error
    if choice not in subjects:
        choice='dflt'
    statement = "SELECT %s FROM `%s`.`%s`" % (columns, db.name, subjects[choice])
    The code checks whether choice is a valid key. If not, it changes the choice to a valid key. You could instead use a default dictionary:
    Code:
    import collections
    subjects = collections.defaultdict(lambda: 'Science', {'sci': 'Science', 'mth': 'Math', 'lit': 'Literature', 'art': 'Art'})
    ...
    statement = "SELECT %s FROM `%s`.`%s`" % (columns, db.name, subjects[choice])
    Here, you don't need to check whether a key exists. If it doesn't, you'll get the default value rather than a thrown KeyError.

    As the comment in the first sample suggests, you could instead signal an error:
    Code:
    # class InputError must be defined, as it's not a built-in
    if choice not in subjects:
        throw InputError("'%s' is not a valid choice." % (choice))
    statement = "SELECT %s FROM `%s`.`%s`" % (columns, db.name, subjects[choice])
    where you define an exception handler elsewhere that sets the HTTP status and outputs an error message. Of course, the above code shouldn't appear as-is, but should be integrated into functions or methods.

    The link on "coupling" in my previous post explains one of the concepts involved. "Coupling" is a broad topic and merits a fair bit of time to study it. A newer programming paradigm, Aspect Oriented Programming, focuses on reducing coupling. Don't be too concerned with AOP right now; it should remain a point on the horizon.

    Another concept involved is "information disclosure". I don't have any links on that topic at large, but "Writing Error Messages for Security Features" has a section on "information disclosure in error messages", which explains it well enough.

    "Atomic" refers to values that can't be broken down, as opposed to "compound" or "aggregate" values, which are collections of other values. This comes from the original Greek meaning of atom: uncut. Lists, dictionaries and structures are examples of compound types; "[0,2,4]" and "{'one': 1, 'zed': 0}" are compound values. When it comes to databases, you might see the terms "simple domains", "nonsimple domains" and "complex domains"; the former basically means "atomic types" and the latter two mean "aggregate types".

    "Interpolation" here means substituting a value into a string. The % operator in Python is an interpolation operator. PHP and Python interpolate values from variables quite easily: "SELECT $columns FROM $table" will interpolate the values of the variables $columns and $table. In Ruby, you use #{...}: "SELECT #{columns} FROM #{table}". #{...} lets you interpolate expressions, not just variables, which makes it more powerful.

    A database driver is the software that supports interaction with the database. For Python, you might use MySQLdb or MySQL Connector/Python.

    Queries have their own language: their own grammar, vocabulary and parts-of-speech. As natural languages have nouns, verbs, adjectives, noun-phrases &c., SQL has commands (or actions), clauses, conditions, expressions, values, identifiers (names) and so on (if you're curious, you can study SQL's grammar in Backus-Naur form, or BNF). Prepared statements let you treat a very limited set of these as parameters, which are like function arguments, that can be replaced at a later point by specific values. (The DB driver will bind values in prepared statements rather like the Python interpreter binding values to variables when a function is called.) This limited set of terms usually doesn't include identifiers (column names, table names) or lists (those compound values previously mentioned). For example, consider the statement:
    Code:
    SELECT number, name, symbol 
        FROM elements 
        WHERE group='p' AND oxidation IN (1,3,5)
    which selects elements from a hypothetical periodic table. For most DB drivers, none of the identifiers (number, name, symbol, elements, group and valence) can be turned into parameters, nor the action (SELECT), nor the clause predicates (FROM, WHERE), nor the compound value ((1,3,5)) used in the IN statement, nor any phrases (e.g. group='p', FROM elements). The only part that can be parameterized is the value 'p'.

    "Structure" refers to data structure, i.e. how you've defined your tables: the column names, their types, their primary and foreign keys. I've also seen the term "intension" refer to this, as opposed to "extension"; the intension of a table is meta-information (information about the table), while the extension of a table is the information stored in a table. Basically, when using SQL the structure is your CREATE statement. Add the ALTER and DROP commands and you've got the Data Definition Language (DDL) portion of SQL, which deals exclusively with intensions. Extensions are handled by the Data Manipulation Language (DML) portion: SELECT, INSERT, UPDATE and DELETE statements.

    As for the gruff nature of my writing, it doesn't communicate annoyance. It's just a very straight-forward, no-nonsense communication style.
    Be sure to read all pages linked in this post; they have further information that should prove useful. When asking for help, make sure you follow Eric Raymond's and Jon Skeet's guidelines for prompt, accurate responses. Please answer any questions I ask; they're not rhetorical (probably). Any posted code is intended as illustrative example, rather than a solution to your problem to be copied without alteration. Study it to learn how to write your own solution.
    Misson, not Mission.

  7. #7
    sorahb is offline x10Hosting Member sorahb is an unknown quantity at this point
    Join Date
    Nov 2009
    Posts
    1

    Re: Quick Python Help!

    Thanks for the help.
    Last edited by sorahb; 01-15-2010 at 07:48 AM.

  8. #8
    rewegan is offline x10Hosting Member rewegan is an unknown quantity at this point
    Join Date
    Nov 2009
    Posts
    4

    Re: Quick Python Help!

    Wow! That was a big help! Thanks a lot! I'll let you know if I need anything else.

    Thanks again.

+ Reply to Thread

Similar Threads

  1. How to run Python on X10Hosting
    By ah-blabla in forum Tutorials
    Replies: 16
    Last Post: 12-29-2010, 07:01 PM
  2. Replies: 5
    Last Post: 07-10-2009, 03:30 AM
  3. Python / MySQLdb
    By Korexio in forum Free Hosting
    Replies: 9
    Last Post: 11-29-2007, 08:29 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
x10hosting free hosting for the masses
dedicated servers