development Accounting a écrit :
> Hello,
>
> I am trying to make a small TG application, which should save PDF file.
> It stores letters in a PDF format in a relational database.
>
> Do you believe it is a good idea to use a class as below? Any idea welcome.
>
> class Letters(Entity):
>       has_field('Description_letter', Unicode(360))   
>       DocPDF = BoolCol()   link to a pdf file save as a binary
>
> Kind regards,
>   
There are different issues at stake here...

    * First point: many people will argue that files should not be
      stored in a database but put on the filesystem. This is possible
      as long as the original filename is kept in the db and the id from
      the database is used for the storage name. This solution makes
      sure that you won't have conflict in names because the db id is a
      primary key. This also ensures you won't have special characters
      to encode on your server's filesystem and last but not least it
      makes possible a solution were you serve the file as a stream
      without loading everything in memory from the db.
    * Second point: if you really want to have the files in the db,
      which is an option that can make sense in some cases. In those
      cases you will either want to use a deferred in the column to make
      sure the actual file data is not fetched in the same call as the
      lettre instance. Or you will need to create a different table just
      to hold the file data.

The example for storage in the db using SQLAlchemy (no elixir here sorry 
:)) would be:
-----------------------------
# import stuff here...

class Letter(object): pass

letters_table = Table(letters, metadata,
        Column('letterid', Integer, primary_key=True),
        Column('reference', Unicode(50), unique=True),
        Column('size', Integer, nullable=False), # filesize in bytes
        Column('filename',  Unicode(360), nullable=False, unique=True), 
# original name before storage
        )

class LetterData(object): pass

letters_data_table = Table(lettersdata, metadata,
        Column('letterid', Integer, ForeignKey(letters_table.c.letterid)),
        Column('data', BLOB(10000))
        )

letters_mapper = assign_mapper(session.context, Letter, letters_table, 
properties=dict(
        data=relation(LetterData, backref=letter, lazy=True)
        **)
)
lettersdata_mapper = assign_mapper(session.context, LetterData, 
letters_data_table)
-----------------------------

This is just a rough exemple of how to do it (I did not test the code). 
This model could then be accessed by:

-----------------------------
# some import stuff here
from myproj.model import Letter

class Root(controllers.RootController):
    def somecontrollermethod(self, reference):
        letter = Letter.select(Letter.c.reference=='2007/0012-AAC')
        return letter.data
-----------------------------

the data will be fetched from the database only when you do "return 
letter.data" not when you create "letter"

The example using a storage on the disk would be easier since you would 
only keep references to a file (dbid, original filename, size, letter 
reference) an then fetch the data from the disk... (remember to use the 
id of your record as the filename in the storage area to avoid 
complications with duplicates)

Hope this helps.
Florent.


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"TurboGears" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/turbogears?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to